package com.ruoyi.project.common.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.project.business.enums.ReadStatusEnum;
import com.ruoyi.project.common.ChatRoomActiveEnum;
import com.ruoyi.project.common.domain.MessageChat;
import com.ruoyi.project.common.domain.MessageChatUser;
import com.ruoyi.project.common.domain.MessageContentUser;
import com.ruoyi.project.common.dto.MessageChatContentDto;
import com.ruoyi.project.common.dto.MessageChatDto;
import com.ruoyi.project.common.dto.MessageContentUserDto;
import com.ruoyi.project.common.mapper.MessageChatMapper;
import com.ruoyi.project.common.service.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 聊天室Service业务层处理
 *
 * @author jubs
 * @date 2024-05-14
 */
@Service
public class MessageChatServiceImpl extends ServiceImpl<MessageChatMapper, MessageChat> implements IMessageChatService {
    @Resource
    private MessageChatMapper messageChatMapper;

    @Resource
    private IMessageContentUserService iMessageContentUserService;

    @Resource
    private IMessageChatContentService iMessageChatContentService;
    @Resource
    private IMessageChatUserService iMessageChatUserService;


    @Override
    public List<MessageChatDto> getChatRoomByUserIds(List<Long> userIds, Long quotationId, String chatName) {
        return messageChatMapper.getChatRoomByUserIds(userIds, quotationId, chatName);
    }

    @Override
    public int readMessage(MessageChatDto dto) {
        //获取聊天室id
        Long chatRoomId = dto.getId();
        //变更聊天室为激活
        //激活当前聊天室
        iMessageChatUserService.update(
                Wrappers.<MessageChatUser>lambdaUpdate()
                        .eq(MessageChatUser::getUserId, SecurityUtils.getUserId())
                        .eq(MessageChatUser::getMessageChatId, chatRoomId)
                        .set(MessageChatUser::getActive, 0)
                        .set(MessageChatUser::getUpdateBy, SecurityUtils.getUserId().toString())
                        .set(MessageChatUser::getUpdateTime, DateUtils.getNowDate())
        );
        //取消激活其他聊天室
        iMessageChatUserService.update(
                Wrappers.<MessageChatUser>lambdaUpdate()
                        .eq(MessageChatUser::getUserId, SecurityUtils.getUserId())
                        .ne(MessageChatUser::getMessageChatId, chatRoomId)
                        .set(MessageChatUser::getActive, 1)
                        .set(MessageChatUser::getUpdateBy, SecurityUtils.getUserId().toString())
                        .set(MessageChatUser::getUpdateTime, DateUtils.getNowDate())
        );

        //变更该聊天室下 所有的未读信息状态为已读
        List<MessageContentUserDto> messageContentUserDtos =
                iMessageContentUserService.getUnReadMessageByUserIdAndChatRoom(SecurityUtils.getUserId(), chatRoomId);
        Date date = DateUtils.getNowDate();
        if (!messageContentUserDtos.isEmpty()) {
            List<MessageContentUser> updateData = messageContentUserDtos.stream().map(item -> {
                MessageContentUser messageContentUser = new MessageContentUser();
                BeanUtils.copyBeanProp(messageContentUser, item);
                messageContentUser.setReadStatus(ReadStatusEnum.READ.getValue());
                messageContentUser.setUpdateTime(date);
                messageContentUser.setUpdateBy(SecurityUtils.getStrUserId());
                return messageContentUser;
            }).collect(Collectors.toList());
            iMessageContentUserService.updateBatchById(updateData);
        }
        //除开该聊天室，查询其余未读讯息
        return iMessageContentUserService.getUnReadMessageByUserIdNeChatRoomId(SecurityUtils.getUserId(), chatRoomId);
    }

    @Override
    public List<MessageChatDto> getChatRoomByQuery(MessageChatDto messageChatDto) {
        Long currentUserId = SecurityUtils.getUserId();
        List<MessageChatDto> chatRooms = messageChatMapper.getChatRoomByUserIds(
                Collections.singletonList(SecurityUtils.getUserId()), null, messageChatDto.getChatName());
        chatRooms = chatRooms.stream().filter(item -> ChatRoomVisibleEnum.SHOW.getCode().equals(item.getVisible())).collect(Collectors.toList());
        if (!chatRooms.isEmpty()) {
            // 按照active排序 0 优先在前
            chatRooms = chatRooms.stream().sorted((o1, o2) -> o2.getActive().compareTo(o1.getActive())).collect(Collectors.toList());
            List<MessageChatDto> activeChatRooms = chatRooms.stream().filter(chatRoom -> ChatRoomActiveEnum.TOP.getCode().equals(chatRoom.getActive())).collect(Collectors.toList());

            if (!activeChatRooms.isEmpty()) {
                //查询被激活的聊天室 或者置顶的聊天室  聊天记录
                //step 1: 查询 从当前时间向前的10条聊天记录
                List<MessageChatContentDto> messageChatContents = iMessageChatContentService.getMessageChatContentList(activeChatRooms.get(0).getId());
                chatRooms.get(0).setChatContentList(messageChatContents);
            } else {
                List<MessageChatContentDto> messageChatContents = iMessageChatContentService.getMessageChatContentList(chatRooms.get(0).getId());
                chatRooms.get(0).setChatContentList(messageChatContents);
            }
            Map<String, Object> chatRoomUnRead = markUnreadMessage(
                    chatRooms.stream().map(MessageChatDto::getId).collect(Collectors.toList()),
                    Collections.singletonList(currentUserId));
            for (MessageChatDto chatRoom : chatRooms) {
                if (chatRoomUnRead.containsKey(chatRoom.getId() + "__" + currentUserId)) {
                    chatRoom.setHasUnReadMessage(true);
                }
                if (chatRoom.isHasUnReadMessage()) {
                    chatRoom.setMaxUnReadMessageTime(
                            ((Date) chatRoomUnRead.get(chatRoom.getId() + "__" + currentUserId + "lastUnReadTime")));
                    chatRoom.setUnReadMessageCount(
                            (Integer) chatRoomUnRead.get(chatRoom.getId() + "__" + currentUserId + "unReadNum"));
                }
            }
        }
        return chatRooms;
    }


    Map<String, Object> markUnreadMessage(List<Long> chatRoomsId, List<Long> userIds) {
        Map<String, Object> result = new HashMap<>();
        List<MessageContentUserDto> contentUserDtos = iMessageContentUserService.markUnReadMessage(chatRoomsId,
                userIds);
        // 以 聊天室+接收人分组
        Map<String, List<MessageContentUserDto>> groupByChatRoomIdAndUserId = contentUserDtos.stream()
                .collect(Collectors.groupingBy(it -> it.getMessageChatId() + "__" + it.getReceiveUserId()));


        if (!groupByChatRoomIdAndUserId.isEmpty()) {
            //循环此分组
            for (String key : groupByChatRoomIdAndUserId.keySet()) {
                List<MessageContentUserDto> messageContentUserDtos = groupByChatRoomIdAndUserId.get(key);

                for (MessageContentUserDto messageContentUserDto : messageContentUserDtos) {
                    //有未读讯息
                    if (key.contains(
                            messageContentUserDto.getMessageChatId() + "__" + messageContentUserDto.getReceiveUserId())
                            && messageContentUserDto.getUnReadMessage() > 0) {
                        //设置最新的一条未读信息的产生的事件
                        result.put(key + "lastUnReadTime", messageContentUserDto.getMaxUnReadMessageTime());
                        result.put(key, true);
                    } else {
                        result.put(key, false);
                    }
                }
                boolean flag = !messageContentUserDtos.isEmpty();
                if (flag) {
                    //计算总数
                    Integer unReadNum = 0;
                    for (MessageContentUserDto messageContentUserDto : messageContentUserDtos) {
                        unReadNum += messageContentUserDto.getUnReadMessage();
                    }
                    result.put(key + "unReadNum", unReadNum);
                }
            }
        }
        return result;

    }
}
