package com.sonic.frog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.sonic.frog.dao.AiUserStatDao;
import com.sonic.frog.domain.bo.AiGiftRankBo;
import com.sonic.frog.domain.bo.AiHeartbeatRankBo;
import com.sonic.frog.domain.bo.ChatRankBo;
import com.sonic.frog.domain.entity.AiUser;
import com.sonic.frog.domain.output.AiChatRankOutput;
import com.sonic.frog.domain.output.AiGiftRankOutput;
import com.sonic.frog.domain.output.AiHeartbeatRankOutput;
import com.sonic.frog.service.AiUserSearchService;
import com.sonic.frog.service.AiUserService;
import com.sonic.frog.service.RankService;
import com.sonic.frog.utils.BeanConvert;
import com.sonic.frog.utils.RedisKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RankServiceImpl implements RankService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisKeyUtils redisKeyUtils;
    @Autowired
    private AiUserStatDao aiUserStatDao;
    @Autowired
    private AiUserService aiUserService;
    @Autowired
    private AiUserSearchService aiUserSearchService;

    @Override
    public int chatRankJob() {
        //统计榜单top 120 的数据
        List<ChatRankBo> boList = aiUserStatDao.queryChatRank(120);
        //将榜单数据写入redis缓存中，过期时间7天吧
        stringRedisTemplate.opsForValue().set(redisKeyUtils.chatRankKey(), JSONObject.toJSONString(boList), 7, TimeUnit.DAYS);
        return boList.size();
    }

    @Override
    public List<AiChatRankOutput> chatRank(Long userId, Integer limit) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKeyUtils.chatRankKey());
        if(StringUtils.isEmpty(cacheStr)) {
            return Collections.emptyList();
        }
        //转换成列表对象
        List<ChatRankBo> boList = JSONObject.parseArray(cacheStr, ChatRankBo.class);
        if(CollectionUtils.isEmpty(boList)) {
            return Collections.emptyList();
        }
        List<Long> idList = boList.stream().map(ChatRankBo::getAiId).collect(Collectors.toList());
        Map<Long, Integer> chatNumMap = boList.stream().collect(Collectors.toMap(ChatRankBo::getAiId, ChatRankBo::getChatNum));
        Map<Long, Integer> likedNumMap = boList.stream().collect(Collectors.toMap(ChatRankBo::getAiId, ChatRankBo::getLikedNum));
        //获取AI基础信息
        List<AiUser> list = aiUserService.list(Wrappers.<AiUser>lambdaQuery().in(AiUser::getAiId, idList).eq(AiUser::getIsDelete, false));
        //排序，根据idList的顺序对list进行排序
        list.sort(Comparator.comparingInt(o -> idList.indexOf(o.getAiId())));
        //获取前100条数据
        list = list.subList(0, Math.min(list.size(), limit));
        //获取字典数据
        Map<String, String> aiDictNameMap = aiUserSearchService.mapNameByCodeList(list);
        //批量获取聊天次数
        List<AiChatRankOutput> outputList = Lists.newArrayList();
        int rankNo = 1;
        for (AiUser aiUser : list) {
            AiChatRankOutput output = BeanConvert.copeBean(aiUser, AiChatRankOutput.class);
            //组装字典数据
            output.setRoleName(aiDictNameMap.get(aiUser.getRoleCode()));
            output.setCharacterName(aiDictNameMap.get(aiUser.getCharacterCode()));
            output.setTagName(aiDictNameMap.get(aiUser.getTagCode()));
            output.setChatNum(chatNumMap.get(aiUser.getAiId()));
            output.setLikedNum(likedNumMap.get(aiUser.getAiId()));
            output.setRankNo(rankNo++);
            outputList.add(output);
        }
        return outputList;
    }

    @Override
    public int aiHeartbeatRankJob() {
        //统计榜单top 120 的数据
        List<AiHeartbeatRankBo> boList = aiUserStatDao.queryAiHeartbeatRank(120);
        //将榜单数据写入redis缓存中，过期时间7天吧
        stringRedisTemplate.opsForValue().set(redisKeyUtils.aiHeartbeatRankKey(), JSONObject.toJSONString(boList), 7, TimeUnit.DAYS);
        return boList.size();
    }

    @Override
    public List<AiHeartbeatRankOutput> aiHeartbeatRank(Long userId, Integer limit) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKeyUtils.aiHeartbeatRankKey());
        if(StringUtils.isEmpty(cacheStr)) {
            return Collections.emptyList();
        }
        //转换成列表对象
        List<AiHeartbeatRankBo> boList = JSONObject.parseArray(cacheStr, AiHeartbeatRankBo.class);
        if(CollectionUtils.isEmpty(boList)) {
            return Collections.emptyList();
        }
        List<Long> idList = boList.stream().map(AiHeartbeatRankBo::getAiId).collect(Collectors.toList());
        Map<Long, BigDecimal> heartbeatValTotalMap = boList.stream().collect(Collectors.toMap(AiHeartbeatRankBo::getAiId, AiHeartbeatRankBo::getHeartbeatValTotal));
        Map<Long, Integer> likedNumMap = boList.stream().collect(Collectors.toMap(AiHeartbeatRankBo::getAiId, AiHeartbeatRankBo::getLikedNum));

        //获取AI基础信息
        List<AiUser> list = aiUserService.list(Wrappers.<AiUser>lambdaQuery().in(AiUser::getAiId, idList).eq(AiUser::getIsDelete, false));
        //排序，根据idList的顺序对list进行排序
        list.sort(Comparator.comparingInt(o -> idList.indexOf(o.getAiId())));
        //获取前100条数据
        list = list.subList(0, Math.min(list.size(), limit));
        //获取字典数据
        Map<String, String> aiDictNameMap = aiUserSearchService.mapNameByCodeList(list);
        //批量获取聊天次数
        List<AiHeartbeatRankOutput> outputList = Lists.newArrayList();
        int rankNo = 1;
        for (AiUser aiUser : list) {
            AiHeartbeatRankOutput output = BeanConvert.copeBean(aiUser, AiHeartbeatRankOutput.class);
            //组装字典数据
            output.setRoleName(aiDictNameMap.get(aiUser.getRoleCode()));
            output.setCharacterName(aiDictNameMap.get(aiUser.getCharacterCode()));
            output.setTagName(aiDictNameMap.get(aiUser.getTagCode()));
            output.setHeartbeatValTotal(heartbeatValTotalMap.get(aiUser.getAiId()));
            output.setLikedNum(likedNumMap.get(aiUser.getAiId()));
            output.setRankNo(rankNo++);
            outputList.add(output);
        }
        return outputList;
    }


    @Override
    public int giftRankJob() {
        //统计榜单top 120 的数据
        List<AiGiftRankBo> boList = aiUserStatDao.queryAiGiftRank(120);
        //将榜单数据写入redis缓存中，过期时间7天吧
        stringRedisTemplate.opsForValue().set(redisKeyUtils.aiGiftRankKey(), JSONObject.toJSONString(boList), 7, TimeUnit.DAYS);
        return boList.size();
    }

    @Override
    public List<AiGiftRankOutput> giftRank(Long userId, Integer limit) {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKeyUtils.aiGiftRankKey());
        if(StringUtils.isEmpty(cacheStr)) {
            return Collections.emptyList();
        }
        //转换成列表对象
        List<AiGiftRankBo> boList = JSONObject.parseArray(cacheStr, AiGiftRankBo.class);
        if(CollectionUtils.isEmpty(boList)) {
            return Collections.emptyList();
        }
        List<Long> idList = boList.stream().map(AiGiftRankBo::getAiId).collect(Collectors.toList());
        Map<Long, Long> giftCoinNumMap = boList.stream().collect(Collectors.toMap(AiGiftRankBo::getAiId, AiGiftRankBo::getGiftCoinNum));
        Map<Long, Integer> likedNumMap = boList.stream().collect(Collectors.toMap(AiGiftRankBo::getAiId, AiGiftRankBo::getLikedNum));
        //获取AI基础信息
        List<AiUser> list = aiUserService.list(Wrappers.<AiUser>lambdaQuery().in(AiUser::getAiId, idList).eq(AiUser::getIsDelete, false));
        //排序，根据idList的顺序对list进行排序
        list.sort(Comparator.comparingInt(o -> idList.indexOf(o.getAiId())));
        //获取前100条数据
        list = list.subList(0, Math.min(list.size(), limit));
        //获取字典数据
        Map<String, String> aiDictNameMap = aiUserSearchService.mapNameByCodeList(list);
        //批量获取聊天次数
        List<AiGiftRankOutput> outputList = Lists.newArrayList();
        int rankNo = 1;
        for (AiUser aiUser : list) {
            AiGiftRankOutput output = BeanConvert.copeBean(aiUser, AiGiftRankOutput.class);
            //组装字典数据
            output.setRoleName(aiDictNameMap.get(aiUser.getRoleCode()));
            output.setCharacterName(aiDictNameMap.get(aiUser.getCharacterCode()));
            output.setTagName(aiDictNameMap.get(aiUser.getTagCode()));
            output.setGiftCoinNum(giftCoinNumMap.get(aiUser.getAiId()));
            output.setLikedNum(likedNumMap.get(aiUser.getAiId()));
            output.setRankNo(rankNo++);
            outputList.add(output);
        }
        return outputList;
    }

}
