package com.luojia_channel.modules.interact.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.luojia_channel.common.domain.page.ScrollPageResponse;
import com.luojia_channel.common.utils.PageUtil;
import com.luojia_channel.common.utils.RedisUtil;
import com.luojia_channel.common.utils.UserContext;
import com.luojia_channel.modules.interact.dto.ChatItemDTO;
import com.luojia_channel.modules.interact.dto.ChatPageQueryDTO;
import com.luojia_channel.modules.interact.service.ChatService;
import com.luojia_channel.modules.message.dto.MessageResponse;
import com.luojia_channel.modules.message.entity.MessageDO;
import com.luojia_channel.modules.message.mapper.MessageMapper;
import com.luojia_channel.modules.user.entity.User;
import com.luojia_channel.modules.user.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService {

    private final MessageMapper messageMapper;
    private final UserMapper userMapper;
    private final RedisUtil redisUtil;

    @Override
    public ScrollPageResponse<ChatItemDTO> getChatList(ChatPageQueryDTO chatPageQueryDTO) {
        /*
        Long userId = UserContext.getUserId();
        IPage<ChatItemDTO> chatPage = messageMapper.selectChatList(PageUtil.convert(chatPageQueryDTO), userId);
        return PageResponse.<ChatItemDTO>builder()
                .current(chatPage.getCurrent())
                .size(chatPage.getSize())
                .total(chatPage.getTotal())
                .records(chatPage.getRecords())
                .build();
         */
        Long userId = UserContext.getUserId();
        String key = "chat:user_list:" + userId;

        return redisUtil.scrollPageQuery(key, ChatItemDTO.class, chatPageQueryDTO,
                (chatUserIds) -> {
                    List<ChatItemDTO> chatItems = new ArrayList<>();
                    List<Long> latestMessageIds = new ArrayList<>();
                    List<User> users = userMapper.selectByIdsOrderByField(chatUserIds);
                    for(Long chatUserId : chatUserIds){
                        String messageKey = "chat:history:" + Math.min(userId, chatUserId) + ":" +Math.max(userId, chatUserId);
                        // 获取zset中最新的messageId
                        Long latestMessageId = redisUtil.zRevMaxValue(messageKey);
                        latestMessageIds.add(latestMessageId);
                    }
                    List<MessageDO> messageDOS = messageMapper.selectByIdsOrderByField(latestMessageIds);
                    int i=0;
                    for(User user : users){
                        ChatItemDTO chatItemDTO = ChatItemDTO.builder()
                                .chatUserId(user.getId())
                                .avatar(user.getAvatar())
                                .username(user.getUsername())
                                .latestMessage(messageDOS.get(i).getContent())
                                .latestTime(messageDOS.get(i).getCreateTime())
                                .build();
                        chatItems.add(chatItemDTO);
                        i++;
                    }

                    return chatItems;
                });
    }

    @Override
    public ScrollPageResponse<MessageResponse> getChatHistory(ChatPageQueryDTO chatPageQueryDTO) {
        /*
        Long userId = UserContext.getUserId();
        Long chatUserId = chatPageQueryDTO.getChatUserId();
        LambdaQueryWrapper<MessageDO> queryWrapper = Wrappers.lambdaQuery(MessageDO.class)
                .eq(MessageDO::getSenderId, userId)
                .eq(MessageDO::getReceiverId, chatUserId)
                .or()
                .eq(MessageDO::getReceiverId, userId)
                .eq(MessageDO::getSenderId, chatUserId)
                .orderByDesc(MessageDO::getCreateTime);
        // 查询的是私信消息
        queryWrapper.eq(MessageDO::getMessageType, 1);
        IPage<MessageDO> page = messageMapper.selectPage(PageUtil.convert(chatPageQueryDTO), queryWrapper);
        User chatUser = userMapper.selectById(chatUserId);
        return PageUtil.convert(page, (message) -> {
            MessageResponse messageResponse = BeanUtil.copyProperties(message, MessageResponse.class);
            if(messageResponse.getSenderId().equals(userId)) {
                messageResponse.setSenderAvatar(UserContext.getAvatar());
                messageResponse.setSenderName(UserContext.getUsername());
            }else{
                messageResponse.setSenderAvatar(chatUser.getAvatar());
                messageResponse.setSenderName(chatUser.getUsername());
            }
            return messageResponse;
        });
         */

        // 改成滚动分页查询
        Long userId = UserContext.getUserId();
        Long chatUserId = chatPageQueryDTO.getChatUserId();
        String key = "chat:history:" + Math.min(userId, chatUserId) + ":" +Math.max(userId, chatUserId);
        return redisUtil.scrollPageQuery(key, MessageResponse.class, chatPageQueryDTO,
                (messageIds) -> {
                    List<MessageDO> messageDOS = messageMapper.selectByIdsOrderByField(messageIds);
                    User chatUser = userMapper.selectById(chatUserId);
                    List<MessageResponse> messageResponses = new ArrayList<>();
                    for(MessageDO message : messageDOS){
                        MessageResponse messageResponse = BeanUtil.copyProperties(message, MessageResponse.class);
                        if(messageResponse.getSenderId().equals(userId)) {
                            messageResponse.setSenderAvatar(UserContext.getAvatar());
                            messageResponse.setSenderName(UserContext.getUsername());
                        }else{
                            messageResponse.setSenderAvatar(chatUser.getAvatar());
                            messageResponse.setSenderName(chatUser.getUsername());
                        }
                        messageResponses.add(messageResponse);
                    }
                    return messageResponses;
                });
    }
}
