package com.sonic.frog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.sonic.frog.dao.AiUserDao;
import com.sonic.frog.domain.entity.AiUser;
import com.sonic.frog.domain.entity.AiUserExt;
import com.sonic.frog.domain.entity.AiUserStat;
import com.sonic.frog.domain.output.*;
import com.sonic.frog.service.*;
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 java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class HomeRecommendV2ServiceImpl implements HomeRecommendV2Service {

    @Autowired
    private RankService rankService;
    @Autowired
    private AiUserService aiUserService;
    @Autowired
    private AiUserExtService aiUserExtService;
    @Autowired
    private AiUserStatService aiUserStatService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedisKeyUtils redisKeyUtils;
    @Autowired
    private AiUserDao aiUserDao;

    @Override
    public void updateCache() {
        //处理 mostChat 的缓存数据
        List<AiChatRankOutput> mostChatList = rankService.chatRank(null, 20);
        //处理 mustCrush 的缓存数据
        List<AiHeartbeatRankOutput> mostCrushList = rankService.aiHeartbeatRank(null, 20);
        //处理 starAChat 的缓存数据
        List<StartChatOutput> startChatList = startChatList();
        //处理 mustGifted 的缓存数据
        List<AiGiftRankOutput> mostGiftedList = rankService.giftRank(null, 20);
        //将数据缓存到redis中
        HomeRecommendV2Output output = new HomeRecommendV2Output();
        output.setMostChat(mostChatList);
        output.setMustCrush(mostCrushList);
        output.setStarAChat(startChatList);
        output.setMustGifted(mostGiftedList);
        //写入redis缓存1天
        stringRedisTemplate.opsForValue().set(redisKeyUtils.homeRecommendV2CacheKey(), JSONObject.toJSONString(output), 1, TimeUnit.DAYS);
    }

    private List<StartChatOutput> startChatList() {
        log.info("===> startChatList start");
        List<StartChatOutput> outputList = Lists.newArrayList();
        List<Long> idList1 = aiUserDao.homeRecommend(true, 20);
        //数量不够，补数
        if(CollectionUtils.isEmpty(idList1) || idList1.size() < 4) {
            List<Long> idList2 = aiUserDao.homeRecommend(false, 20 - idList1.size());
            idList1.addAll(idList2);
        }
        if(CollectionUtils.isEmpty(idList1)) {
            log.info("mostChatList is empty 1");
            return Collections.emptyList();
        }
        List<AiUser> aiUserList1 = aiUserService.list(Wrappers.<AiUser>lambdaQuery().in(AiUser::getAiId, idList1));
        if(CollectionUtils.isEmpty(aiUserList1)) {
            log.info("mostChatList is empty 2");
            return Collections.emptyList();
        }
        List<Long> aiIdList = aiUserList1.stream().map(AiUser::getAiId).collect(Collectors.toList());
        //批量查询扩展信息
        List<AiUserExt> aiUserExtList = aiUserExtService.list(Wrappers.<AiUserExt>lambdaQuery()
                .select(AiUserExt::getAiId, AiUserExt::getDialoguePrologueSound, AiUserExt::getSupportingContent)
                .in(AiUserExt::getAiId, aiIdList));
        Map<Long, AiUserExt> aiUserExtMap = aiUserExtList.stream().collect(Collectors.toMap(AiUserExt::getAiId, aiUserExt -> aiUserExt));
        //批量查询点赞数
        List<AiUserStat> aiUserStatList = aiUserStatService.list(Wrappers.<AiUserStat>lambdaQuery().in(AiUserStat::getAiId, aiIdList));
        Map<Long, AiUserStat> aiUserStatMap = aiUserStatList.stream().collect(Collectors.toMap(AiUserStat::getAiId, aiUserStat -> aiUserStat));
        for (AiUser aiUser : aiUserList1) {
            AiUserExt aiUserExt = aiUserExtMap.get(aiUser.getAiId());
            AiUserStat aiUserStat = aiUserStatMap.get(aiUser.getAiId());
            StartChatOutput output = new StartChatOutput();
            output.setAiId(aiUser.getAiId());
            output.setNickname(aiUser.getNickname());
            output.setHeadImg(aiUser.getHeadImg());
            if(aiUserExt != null) {
                output.setDialoguePrologueSound(aiUserExt.getDialoguePrologueSound());
                output.setSupportingContentList(StringUtils.isEmpty(aiUserExt.getSupportingContent()) ? null : JSONObject.parseArray(aiUserExt.getSupportingContent(), String.class));
            }
            output.setLikedNum(aiUserStat == null ? 0 : aiUserStat.getLikedNum());
            output.setCreateTime(aiUser.getCreateTime());
            outputList.add(output);
        }
        return outputList;
    }

    @Override
    public HomeRecommendV2Output recommendList() {
        String cacheStr = stringRedisTemplate.opsForValue().get(redisKeyUtils.homeRecommendV2CacheKey());
        if(StringUtils.isEmpty(cacheStr)) {
            return null;
        }
        HomeRecommendV2Output cacheObject = JSONObject.parseObject(cacheStr, HomeRecommendV2Output.class);
        //处理
        HomeRecommendV2Output output = new HomeRecommendV2Output();
        //随机取20个
        if(CollectionUtils.isNotEmpty(cacheObject.getMostChat())) {
            Collections.shuffle(cacheObject.getMostChat());
            output.setMostChat(cacheObject.getMostChat());
        }
        if(CollectionUtils.isNotEmpty(cacheObject.getMustCrush())) {
            Collections.shuffle(cacheObject.getMustCrush());
            output.setMustCrush(cacheObject.getMustCrush());
        }
        if(CollectionUtils.isNotEmpty(cacheObject.getStarAChat())) {
            //将数据进行分组处理，3天内创建的在前面，三天后创建的在后面
            List<StartChatOutput> list1 = cacheObject.getStarAChat().stream().filter(item -> item.getCreateTime().isAfter(LocalDateTime.now().minusDays(3))).collect(Collectors.toList());
            List<StartChatOutput> list2 = cacheObject.getStarAChat().stream().filter(item -> item.getCreateTime().isBefore(LocalDateTime.now().minusDays(3))).collect(Collectors.toList());
            Collections.shuffle(list1);
            Collections.shuffle(list2);
            list1.addAll(list2);
            List<StartChatOutput> list = list1.size() > 4 ? list1.subList(0, 4) : list1;
            Collections.shuffle(list);
            output.setStarAChat(list);
        }
        if(CollectionUtils.isNotEmpty(cacheObject.getMustGifted())) {
            Collections.shuffle(cacheObject.getMustGifted());
            output.setMustGifted(cacheObject.getMustGifted());
        }
        return output;
    }

}
