package com.sonic.frog.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.sonic.bear.lib.input.EditUserInfoInput;
import com.sonic.bear.lib.output.BaseUserInfoOutput;
import com.sonic.cow.lib.client.NsfwCheckClient;
import com.sonic.frog.dao.ChatSetDao;
import com.sonic.frog.domain.entity.AiUser;
import com.sonic.frog.domain.entity.ChatBubbleDict;
import com.sonic.frog.domain.entity.ChatModelDict;
import com.sonic.frog.domain.entity.ChatSet;
import com.sonic.frog.domain.input.*;
import com.sonic.frog.domain.output.ChatBubbleListOutput;
import com.sonic.frog.domain.output.ChatBubbleOutput;
import com.sonic.frog.domain.output.ChatSetOutput;
import com.sonic.frog.enums.BubbleUnlockTypeEnum;
import com.sonic.frog.enums.HeartbeatLevelEnum;
import com.sonic.frog.enums.ToastResultCode;
import com.sonic.frog.service.*;
import com.sonic.frog.utils.BeanConver;
import com.sonic.frog.utils.BeanConvert;
import com.sonic.lion.lib.client.SubscribeClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 用户与Ai的聊天设定表服务实现类
 */
@Service
@Slf4j
public class ChatSetServiceImpl extends ServiceImpl<ChatSetDao, ChatSet> implements ChatSetService {

    @Autowired
    private AiUserSearchService aiUserSearchService;
    @Autowired
    private ChatModelDictService chatModelDictService;
    @Autowired
    private ChatBubbleDictService chatBubbleDictService;
    @Autowired
    private UserService userService;
    @Autowired
    private AiUserHeartbeatRelationService aiUserHeartbeatRelationService;
    @Autowired
    private HeartbeatLevelDictService heartbeatLevelDictService;
    @Autowired
    private SubscribeClient subscribeClient;
    @Autowired
    private NsfwCheckClient nsfwCheckClient;

    @Override
    public ChatSet getChatSet(Long userId, Long aiId) {
        return getOne(Wrappers.<ChatSet>lambdaQuery().eq(ChatSet::getUserId, userId).eq(ChatSet::getAiId, aiId).last("limit 1"));
    }

    @Override
    public ChatSetOutput getMyChatSet(Long userId, Long aiId) {
        //获取用户与Ai的聊天设定
        ChatSet chatSet = getChatSet(userId, aiId);
        //获取ai的信息
        AiUser aiUser = aiUserSearchService.getAiUserByAiId(aiId);
        ToastResultCode.AI_USER_NOT_EXIST.check(aiUser == null);
        //获取当前用户基础信息
        BaseUserInfoOutput baseUserInfo = userService.baseUserInfo(userId);
        //构建输出
        ChatSetOutput output = new ChatSetOutput();
        output.setAiId(aiId);
        //人物设定 昵称，年龄，性别
        output.setNickname(baseUserInfo.getNickname());
        output.setSex(baseUserInfo.getSex());
        output.setBirthday(baseUserInfo.getBirthday());
        //聊天背景，默认使用ai的主图
        output.setBackgroundImg(aiUser.getHomeImageUrl());
        output.setIsDefaultBackground(true);
        //获取默认对话模型
        ChatModelDict defaultChatModel = chatModelDictService.getDefaultChatModel();
        output.setModelCode(defaultChatModel.getCode());
        output.setModelName(defaultChatModel.getName());
        //自动播放语音，默认关闭
        output.setIsAutoPlayVoice(0);
        if (chatSet != null) {
            //昵称，生日 如果设置了用设置的
            if (StringUtils.isNotEmpty(chatSet.getNickname())) {
                output.setNickname(chatSet.getNickname());
            }
            if (chatSet.getBirthday() != null) {
                output.setBirthday(chatSet.getBirthday());
            }
            //获取我是谁
            output.setWhoAmI(chatSet.getWhoAmI());
            //获取用户设置的对话模型名称
            if (StringUtils.isNotEmpty(chatSet.getModelCode())) {
                output.setModelCode(chatSet.getModelCode());
                output.setModelName(chatModelDictService.getModelNameByCode(chatSet.getModelCode()));
            }
            //聊天背景图片
            if (StringUtils.isNotEmpty(chatSet.getBackgroundImg())) {
                output.setBackgroundImg(chatSet.getBackgroundImg());
                output.setIsDefaultBackground(chatSet.getBackgroundImg().equals(aiUser.getHomeImageUrl()));
            }
            //是否自动播放
            output.setIsAutoPlayVoice(chatSet.getIsAutoPlayVoice() != null ? chatSet.getIsAutoPlayVoice() : 0);
        }
        //聊天气泡
        String userSetBubbleCode = chatSet != null ? chatSet.getBubbleCode() : null;
        ChatBubbleDict chatBubbleDict = chatBubbleDictService.getUserChatBubble(userId, aiId, userSetBubbleCode);
        output.setBubbleCode(chatBubbleDict.getCode());
        output.setBubbleName(chatBubbleDict.getName());
        return output;
    }


    /**
     * 初始化或获取用户与Ai的聊天设定
     *
     * @param userId
     * @param aiId
     * @return
     */
    private ChatSet initAndGetChatSet(Long userId, Long aiId) {
        ChatSet chatSet = getOne(Wrappers.<ChatSet>lambdaQuery().eq(ChatSet::getUserId, userId).eq(ChatSet::getAiId, aiId).last("limit 1"));
        if (chatSet == null) {
            chatSet = new ChatSet();
            chatSet.setUserId(userId);
            chatSet.setAiId(aiId);
            save(chatSet);
        }
        return chatSet;
    }

    @Override
    public void setMyChatSetting(Long userId, SetMyChatSettingInput input) {
        EditUserInfoInput editUserInfoInput = new EditUserInfoInput();
        editUserInfoInput.setUserId(userId);
        editUserInfoInput.setNickname(input.getNickname());
        editUserInfoInput.setBirthday(input.getBirthday());
        //修改用户基础信息
        userService.editUserInfo(editUserInfoInput);

        //初始化或获取用户与Ai的聊天设定
        ChatSet chatSet = initAndGetChatSet(userId, input.getAiId());
        //更新
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getNickname, input.getNickname())
                .set(ChatSet::getBirthday, input.getBirthday())
                .set(ChatSet::getWhoAmI, input.getWhoAmI())
                .eq(ChatSet::getId, chatSet.getId()));
    }

    @Override
    public void setChatModel(Long userId, SetChatModelInput input) {
        //初始化或获取用户与Ai的聊天设定
        ChatSet chatSet = initAndGetChatSet(userId, input.getAiId());
        //更新聊天对话模型
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getModelCode, input.getCode())
                .eq(ChatSet::getId, chatSet.getId()));
    }

    @Override
    public void setChatBubble(Long userId, SetChatBubbleInput input) {
        String code = input.getCode();
        ChatBubbleDict chatBubbleDict = chatBubbleDictService.getChatBubbleDictByCode(code);
        ToastResultCode.CHAT_BUBBLE_NOT_EXIST.check(chatBubbleDict == null);
        BubbleUnlockTypeEnum unlockType = chatBubbleDict.getUnlockType();
        //会员解锁时，判断是否是会员
        if (BubbleUnlockTypeEnum.MEMBER.equals(unlockType)) {
            Boolean isMember = subscribeClient.queryUserIsSubscribe(userId);
            ToastResultCode.SYS_PERMISSION_DENIED.check(isMember == null || !isMember);
        }
        //心动等级解锁时，判断等级是否达到
        if (BubbleUnlockTypeEnum.HEARTBEAT_LEVEL.equals(unlockType)) {
            HeartbeatLevelEnum heartbeatLevelEnum = aiUserHeartbeatRelationService.getHeartbeatLevel(userId, input.getAiId());
            List<HeartbeatLevelEnum> unlockHeartbeatLevelList = heartbeatLevelDictService.getUnlockListByCode(heartbeatLevelEnum);
            ToastResultCode.SYS_PERMISSION_DENIED.check(heartbeatLevelEnum == null || (!unlockHeartbeatLevelList.contains(heartbeatLevelEnum)));
        }
        //初始化或获取用户与Ai的聊天设定
        ChatSet chatSet = initAndGetChatSet(userId, input.getAiId());
        //更新聊天气泡
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getBubbleCode, input.getCode())
                .eq(ChatSet::getId, chatSet.getId()));
    }

    @Override
    public void setBackground(Long userId, Long aiId, String imgUrl) {
        //初始化或获取用户与Ai的聊天设定
        ChatSet chatSet = initAndGetChatSet(userId, aiId);
        //更新聊天背景图
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getBackgroundImg, imgUrl)
                .eq(ChatSet::getId, chatSet.getId()));
    }

    @Override
    public void setIsAutoPlayVoice(Long userId, SetIsAutoPlayVoiceInput input) {
        //判断是否会员
        Boolean isMember = subscribeClient.queryUserIsSubscribe(userId);
        ToastResultCode.SYS_PERMISSION_DENIED.check(isMember == null || !isMember);
        //初始化或获取用户与Ai的聊天设定
        ChatSet chatSet = initAndGetChatSet(userId, input.getAiId());
        //更新聊天背景图
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getIsAutoPlayVoice, input.getIsAutoPlayVoice())
                .eq(ChatSet::getId, chatSet.getId()));
    }

    @Override
    public List<ChatBubbleListOutput> getChatBubbleList(Long userId, ChatBubbleListInput input) {
        //字典列表
        List<ChatBubbleDict> list = chatBubbleDictService.list(Wrappers.<ChatBubbleDict>lambdaQuery()
                .eq(ChatBubbleDict::getIsDelete, false)
                .orderByDesc(ChatBubbleDict::getIsDefault)
                .orderByDesc(ChatBubbleDict::getSort)
        );
        //是否是会员
        Boolean isMember = subscribeClient.queryUserIsSubscribe(userId);
        //用户与AI的心动等级
        HeartbeatLevelEnum heartbeatLevelEnum = aiUserHeartbeatRelationService.getHeartbeatLevel(userId, input.getAiId());
        //解锁了哪些等级
        List<HeartbeatLevelEnum> unlockList = heartbeatLevelDictService.getUnlockListByCode(heartbeatLevelEnum);
        //输出
        List<ChatBubbleListOutput> outputList = Lists.newArrayList();
        list.forEach(chatBubbleDict -> {
            ChatBubbleListOutput output = BeanConver.copeBean(chatBubbleDict, ChatBubbleListOutput.class);
            //会员解锁时，判断是否是会员
            if (BubbleUnlockTypeEnum.MEMBER.equals(chatBubbleDict.getUnlockType())) {
                output.setIsUnlock(isMember != null && isMember);
            } else if (BubbleUnlockTypeEnum.HEARTBEAT_LEVEL.equals(chatBubbleDict.getUnlockType())) {
                //心动等级解锁时，判断等级是否达到
                output.setIsUnlock(heartbeatLevelEnum != null && unlockList.contains(chatBubbleDict.getUnlockHeartbeatLevel()));
            } else {
                output.setIsUnlock(true);
            }
            outputList.add(output);
        });
        return outputList;
    }

    @Override
    public String getChatSetBackground(Long userId, Long aiId) {
        ChatSet chatSet = getChatSet(userId, aiId);
        return chatSet != null ? chatSet.getBackgroundImg() : null;
    }

    @Override
    public void updateIsDelChatted(Long userId, List<Long> aiIdList) {
        if (CollectionUtils.isEmpty(aiIdList)) {
            return;
        }
        update(Wrappers.<ChatSet>lambdaUpdate()
                .eq(ChatSet::getUserId, userId)
                .in(ChatSet::getAiId, aiIdList)
                .set(ChatSet::getIsDelChatted, 1));
    }

    @Override
    public void closeAutoPlayVoice(List<Long> userIdList) {
        update(Wrappers.<ChatSet>lambdaUpdate()
                .set(ChatSet::getIsAutoPlayVoice, false)
                .in(ChatSet::getUserId, userIdList)
                .eq(ChatSet::getIsAutoPlayVoice, true));
    }
}