package com.pz.applet;

import cn.dev33.satoken.annotation.SaIgnore;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pz.common.annotation.Log;
import com.pz.common.annotation.RepeatSubmit;
import com.pz.common.core.controller.BaseController;
import com.pz.common.core.domain.BaseEntity;
import com.pz.common.core.domain.PageQuery;
import com.pz.common.core.domain.R;
import com.pz.common.core.domain.entity.SysUser;
import com.pz.common.core.page.TableDataInfo;
import com.pz.common.core.validate.AddGroup;
import com.pz.common.enums.BusinessType;
import com.pz.system.domain.Message;
import com.pz.system.domain.SessionList;
import com.pz.system.domain.bo.SessionListBo;
import com.pz.system.domain.vo.AvatarUserNameVo;
import com.pz.system.domain.vo.MessageVo;
import com.pz.system.domain.vo.SessionListVo;
import com.pz.system.mapper.MessageMapper;
import com.pz.system.mapper.SessionListMapper;
import com.pz.system.mapper.SysOssMapper;
import com.pz.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 会话列
 *
 * @author ruoyi
 * @date 2023-09-09
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/applet/session")
public class AppletSessionListController extends BaseController {

    private final SessionListMapper sessionListMapper;

    private final SysUserMapper sysUserMapper;

    private final MessageMapper messageMapper;

    /**
     * 查询会话列列表
     */
    @GetMapping("/list")
    public TableDataInfo<SessionListVo> list(SessionListBo bo, PageQuery pageQuery) {
        IPage<SessionListVo> sessionListVoIPage = sessionListMapper.selectVoPage(pageQuery.build(), Wrappers.<SessionList>lambdaQuery().eq(SessionList::getUserId, getUserId()).or().eq(SessionList::getToUserId, getUserId()));
        List<SessionListVo> records = sessionListVoIPage.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            Long userId = getUserId();
            List<SessionListVo> recordsToRemove = new ArrayList<>();
            records.forEach(sessionListVo -> {
                Long toUserId = sessionListVo.getToUserId();
                Long fromUserId = sessionListVo.getUserId();
                if (fromUserId == userId || toUserId == userId) {
                    Long targetUserId = (fromUserId == userId) ? toUserId : fromUserId;
                    sessionListVo.setToUserId(targetUserId);
                    Optional<SysUser> optionalSysUser = Optional.ofNullable(sysUserMapper.selectUserById(targetUserId));
                    optionalSysUser.ifPresent(sysUser -> {
                        sessionListVo.setToUserName(sysUser.getNickName());
                        sessionListVo.setToAvatar(sysUser.getAvatar());
                    });
                    //获取未读消息数以及最后消息时间
                    List<MessageVo> messageVos = messageMapper.selectVoList(Wrappers.<Message>lambdaQuery()
                        .eq(Message::getSender, targetUserId)
                        .eq(Message::getReceiver, getUserId())
                        .eq(Message::getIsRead, 0)
                        .orderByDesc(Message::getCreateTime));
                    if (CollectionUtils.isNotEmpty(messageVos)) {
                        //未读消息数
                        sessionListVo.setUnReadCount(messageVos.size());
                        //最后发送消息时间
                        sessionListVo.setLastTime(messageVos.get(0).getCreateTime());
                        //消息内容
                        sessionListVo.setMessage(messageVos.get(0).getContent());
                    } else {
                        List<MessageVo> messageVoList = messageMapper.selectVoList(Wrappers.<Message>lambdaQuery()
                            .eq(Message::getSender, getUserId())
                            .eq(Message::getReceiver, targetUserId)
                            .eq(Message::getIsRead, 1)
                            .orderByDesc(Message::getCreateTime));
                        if (CollectionUtils.isNotEmpty(messageVoList)) {
                            sessionListVo.setLastTime(messageVoList.get(0).getCreateTime());
                            sessionListVo.setUnReadCount(0);
                        } else {
                            recordsToRemove.add(sessionListVo);
                        }
                    }
                }
            });
            // 执行删除操作
            records.removeAll(recordsToRemove);
        }
        return TableDataInfo.build(sessionListVoIPage);
    }

    /**
     * 获取聊天头像与名称
     *
     * @param toUserId
     * @return
     */
    @GetMapping("/getAvatarUserName/{toUserId}")
    public R<AvatarUserNameVo> getAvatarUserNameVo(@PathVariable Integer toUserId) {
        AvatarUserNameVo avatarUserNameVo = new AvatarUserNameVo();
        //获取我的信息
        Optional.ofNullable(sysUserMapper.selectUserById(getUserId())).ifPresent(
            sysUser -> {
                avatarUserNameVo.setUserName(sysUser.getNickName());
                avatarUserNameVo.setAvatar(sysUser.getAvatar());
            }
        );
        //获取对方信息
        Optional.ofNullable(sysUserMapper.selectUserById(toUserId.longValue())).ifPresent(
            sysUser -> {
                avatarUserNameVo.setToUserName(sysUser.getNickName());
                avatarUserNameVo.setToAvatar(sysUser.getAvatar());
            }
        );
        avatarUserNameVo.setToUserId(toUserId);

        //获取最后一次聊天时间
        Optional.ofNullable(messageMapper.selectOne(Wrappers.<Message>lambdaQuery().eq(Message::getSender, getUserId())
                .eq(Message::getReceiver, toUserId).orderByDesc(BaseEntity::getCreateTime).last("limit 1")))
            .ifPresent(message -> {
                avatarUserNameVo.setStrTime(message.getCreateTime());
            });

        return R.ok(avatarUserNameVo);
    }


    /**
     * 创建会话
     */
    @Log(title = "会话列", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/createSession")
    @SaIgnore
    @Transactional
    public R<Long> add(@Validated(AddGroup.class) @RequestBody SessionListBo bo) {
        //判断我和对方是否创建过会话
        Integer res = sessionListMapper.selectIdByUser(bo.getUserId(), bo.getToUserId());
        if (res != null && res > 0) {
            //有则直接返回
            return R.ok(res.longValue());
        }
        // 创建会话列表对象
        SessionList sessionList = new SessionList();
        sessionList.setUserId(bo.getUserId());
        sessionList.setUnReadCount(0L);
        sessionList.setToUserId(bo.getToUserId());

        // 插入会话列表记录
        sessionListMapper.insert(sessionList);
        return R.ok(sessionList.getId());
    }


    /**
     * 删除会话
     *
     * @param id 主键
     */
    @Log(title = "会话列", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long id) {

        return toAjax(sessionListMapper.deleteById(id));
    }
}