package com.sonic.frog.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.sonic.bear.lib.client.UserNicknamePoolClient;
import com.sonic.bear.lib.client.UserSearchClient;
import com.sonic.bear.lib.enums.OptTypeEnum;
import com.sonic.bear.lib.output.BaseUserInfoOutput;
import com.sonic.cow.lib.client.ImageClient;
import com.sonic.cow.lib.client.NsfwCheckClient;
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.input.CreateEditAiUserInput;
import com.sonic.frog.domain.input.EditAiHeadImgInput;
import com.sonic.frog.domain.output.AiUserExtOutput;
import com.sonic.frog.domain.output.AiUserInfoOutput;
import com.sonic.frog.domain.output.CreateEditAiUserOutput;
import com.sonic.frog.enums.ToastResultCode;
import com.sonic.frog.event.inner.payload.AiImInfoPayload;
import com.sonic.frog.service.*;
import com.sonic.frog.utils.BeanConver;
import com.sonic.frog.utils.RegexUtil;
import com.sonic.lion.lib.client.SubscribeClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Set;

import static com.sonic.frog.enums.Constants.CREATE_AI_NO_LIMIT_USER_ID_LIST;

/**
 * AI用户表服务实现类
 */
@Service
@Slf4j
public class AiUserSetServiceImpl extends ServiceImpl<AiUserDao, AiUser> implements AiUserSetService {
    @Autowired
    private UserNicknamePoolClient userNicknamePoolClient;
    @Autowired
    private AiUserExtService aiUserExtService;
    @Autowired
    private AiDictService aiDictService;
    @Autowired
    private AiUserAlbumService aiUserAlbumService;
    @Autowired
    private TimbreDictService timbreDictService;
    @Autowired
    private ImageStyleDictService imageStyleDictService;
    @Autowired
    private CommonSendMqService commonSendMqService;
    @Autowired
    private AiUserStatService aiUserStatService;
    @Autowired
    private SubscribeClient subscribeClient;

    /**
     * 构造ID生成器的对象
     */
    private final Sequence sequence = new Sequence();
    @Autowired
    private AiUserSearchService aiUserSearchService;
    @Autowired
    private ImageClient imageClient;
    @Autowired
    private UserSearchClient userSearchClient;
    @Autowired
    private NsfwCheckClient nsfwCheckClient;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CreateEditAiUserOutput createEditAiUser(CreateEditAiUserInput input, Long currentUserId) {
        //昵称是否修改
        boolean isNicknameUpdate = true;
        if (input.getAiId() != null) {
            AiUser aiUser = getOne(Wrappers.<AiUser>lambdaQuery().eq(AiUser::getAiId, input.getAiId()).eq(AiUser::getUserId, currentUserId));
            ToastResultCode.SYS_PERMISSION_DENIED.check(aiUser == null);
            isNicknameUpdate = StringUtils.isNotEmpty(aiUser.getNickname()) && !aiUser.getNickname().equals(input.getNickname());
        }
        if (isNicknameUpdate) {
            //昵称重复性判断
            boolean nicknameExist = userNicknamePoolClient.userNicknameExistCheck(input.getNickname());
            ToastResultCode.USER_NICKNAME_EXIST.check(nicknameExist);
        }
        //昵称鉴黄
        nsfwCheckClient.checkContent(input.getNickname());
        //TODO 图片鉴黄
//        s3CheckClient.checkImage(input.getImageUrl());
        Long aiId = 0L;
        AiUser aiUser = null;
        AiImInfoPayload payload = new AiImInfoPayload();
        //是否同步相册默认图
        boolean isSyncAlbumDefault = false;
        //判断添加的图片是否是ai生成的6张图之一
        imageClient.checkImageIsAIGenerated(currentUserId, Lists.newArrayList(input.getImageUrl()));
        //开场白是否变化
        Boolean isDialoguePrologueChange = false;
        //扩展表信息
        AiUserExt aiUserExt = null;
        if (input.getAiId() == null) {
            //创建作者AI虚拟角色限额不足时，提示  非会员1个，会员5个
            if (!CREATE_AI_NO_LIMIT_USER_ID_LIST.contains(currentUserId)) {
                Boolean isMember = subscribeClient.queryUserIsSubscribe(currentUserId);
                Integer aiNum = aiUserSearchService.countAiNumByUserId(currentUserId);
                ToastResultCode.NOT_MEMBER_CREATE_AI_ONE.check((isMember == null || !isMember) && aiNum > 0);
                ToastResultCode.MEMBER_CREATE_AI_MAX_NUM.check(isMember && aiNum >= 5);
            }
            //创建
            //aiId生成
            aiId = sequence.nextId();
            aiUser = BeanConver.copeBean(input, AiUser.class);
            aiUser.setUserId(currentUserId);
            //雪花算法生成
            aiUser.setAiId(aiId);
            //AI虚拟角色的ID暂时不展示，使用创作者账户ID：251843333001XX，增加两位虚拟角色自增长ID即可
            aiUser.setIdCard(getAiUserIdCard(currentUserId));
            //设置基图，创建形象时设置，之后不会变
            aiUser.setBaseImageUrl(input.getImageUrl());
            aiUser.setCreateTime(LocalDateTime.now());
            aiUser.setEditorId(currentUserId);
            aiUser.setEditTime(LocalDateTime.now());
            save(aiUser);
            //扩展表保存
            aiUserExtService.saveOrUpdateAiUserExt(aiId, aiUserExt, input.getAiUserExt(), currentUserId);
            //昵称同步
            userNicknamePoolClient.syncAiNickname(aiId, input.getNickname(), OptTypeEnum.ADD);
            isSyncAlbumDefault = true;
            payload.setAiId(aiId);
            payload.setOptType(AiImInfoPayload.OptType.ADD);
            //初始化Ai统计表
            aiUserStatService.initAiUserStat(aiId);
            //开场白是否变化
            isDialoguePrologueChange = true;
        } else {
            //编辑
            //权限判断-只能自己编辑自己的
            aiUser = getOne(Wrappers.<AiUser>lambdaQuery().eq(AiUser::getAiId, input.getAiId()).eq(AiUser::getUserId, currentUserId));
            ToastResultCode.SYS_PERMISSION_DENIED.check(aiUser == null);
            Long id = aiUser.getId();
            //aiId
            aiId = aiUser.getAiId();
            //性别是不能变的
            Integer sex = aiUser.getSex();
            //形象图改了才同步
            if (StringUtils.isNotEmpty(aiUser.getImageUrl()) && !aiUser.getImageUrl().equals(input.getImageUrl())) {
                isSyncAlbumDefault = true;
            }
            //对象复制更新
            aiUser = BeanConver.copeBean(input, AiUser.class);
            aiUser.setSex(sex);
            aiUser.setId(id);
            updateById(aiUser);
            //扩展表更新
            aiUserExt = aiUserExtService.getAiUserExtByAiId(aiId);
            aiUserExtService.saveOrUpdateAiUserExt(aiUser.getAiId(), aiUserExt, input.getAiUserExt(), currentUserId);
            //昵称同步
            userNicknamePoolClient.syncAiNickname(aiId, input.getNickname(), OptTypeEnum.UPD);
            payload.setAiId(aiId);
            payload.setOptType(AiImInfoPayload.OptType.UPDATE);
            //开场白是否变化
            isDialoguePrologueChange =  !aiUserExt.getDialoguePrologue().equals(input.getAiUserExt().getDialoguePrologue())
                    ||!aiUserExt.getDialogueTimbreCode().equals(input.getAiUserExt().getDialogueTimbreCode())
                    ||!aiUserExt.getDialogueSpeechRate().equals(input.getAiUserExt().getDialogueTimbreCode())
                    ||!aiUserExt.getDialoguePitch().equals(input.getAiUserExt().getDialoguePitch());
        }

        //形象图片同步到相册且为默认图，
        if (isSyncAlbumDefault) {
            aiUserAlbumService.addDefaultAlbum(currentUserId, aiId, input.getImageUrl(), input.getImageWidth(), input.getImageHeight());
        }

        //发送MQ消息进行IM基础信息同步
        commonSendMqService.aiImInfoSendMq(payload);
        //AI变化发送MQ消息
        commonSendMqService.aiChangeMq(aiId, isDialoguePrologueChange, input.getAiId() == null);

        return CreateEditAiUserOutput.builder()
                .aiId(aiId)
                .build();
    }

    /**
     * AI虚拟角色的ID暂时不展示，使用创作者账户ID：251843333001XX，增加两位虚拟角色自增长ID即可
     *
     * @param currentUserId
     * @return
     */
    private String getAiUserIdCard(Long currentUserId) {
        // 先获取当前用户有没有创建过AI，并获取最后一个AI用户的idCard
        AiUser aiUser = getOne(Wrappers.<AiUser>lambdaQuery()
                .eq(AiUser::getUserId, currentUserId)
                .orderByDesc(AiUser::getId)
                .last("limit 1"));

        String idCard;
        if (aiUser != null) {
            String latestIdCard = aiUser.getIdCard();
            // 提取后两位数字并递增
            if (latestIdCard.length() >= 2 && latestIdCard.matches(".*\\d{2}")) {
                String prefix = latestIdCard.substring(0, latestIdCard.length() - 2);
                int number = Integer.parseInt(latestIdCard.substring(latestIdCard.length() - 2));
                idCard = prefix + String.format("%02d", number + 1);
            } else {
                // 如果没有符合格式的后两位数字，则追加"01"
                idCard = latestIdCard + "01";
            }
        } else {
            //获取当前用户的idCard
            BaseUserInfoOutput baseUserInfoOutput = userSearchClient.baseUserInfo(currentUserId);
            String baseIdCard = baseUserInfoOutput.getIdCard();
            // 追加默认起始编号"01"
            idCard = baseIdCard + "01";
        }
        return idCard;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delAiUser(Long aiId, Long currentUserId) {
        //权限判断,非主人不能删除
        AiUser aiUser = getOne(Wrappers.<AiUser>lambdaQuery().eq(AiUser::getAiId, aiId).eq(AiUser::getUserId, currentUserId));
        ToastResultCode.SYS_PERMISSION_DENIED.check(aiUser == null);
        //删除ai用户
        update(Wrappers.<AiUser>lambdaUpdate().eq(AiUser::getAiId, aiId).set(AiUser::getIsDelete, true));
        //删除ai用户扩展
        aiUserExtService.delAiUser(aiId);
        //TODO 1、删除关联信息，这个需要仔细的对一下，看具体要删哪些信息

        //昵称同步
        userNicknamePoolClient.syncAiNickname(aiId, null, OptTypeEnum.DEL);

        //AI变化发送MQ消息
        commonSendMqService.aiChangeMq(aiId, false, false);
    }

    @Override
    public AiUserInfoOutput getMyAiUserInfo(Long aiId, Long currentUserId) {
        AiUser aiUser = getOne(Wrappers.<AiUser>lambdaQuery().eq(AiUser::getAiId, aiId).last("limit 1"));
        if (aiUser == null) {
            return new AiUserInfoOutput();
        }
        //判断只有自己才能查看
        ToastResultCode.SYS_PERMISSION_DENIED.check(aiUser.getUserId() != null && !aiUser.getUserId().equals(currentUserId));
        //基础信息
        AiUserInfoOutput output = BeanConver.copeBean(aiUser, AiUserInfoOutput.class);
        //扩展信息
        AiUserExt aiUserExt = aiUserExtService.getAiUserExtByAiId(aiId);

        //角色, 性格，标签名称
        Set<String> codeList = Sets.newHashSet(aiUser.getRoleCode(), aiUser.getCharacterCode(), aiUser.getTagCode());
        if (aiUserExt != null && aiUserExt.getImageStyleCode() != null) {
            codeList.add(aiUserExt.getImageStyleCode());
        }
        Map<String, String> aiDictNameMap = aiDictService.mapNameByCodeList(codeList);
        output.setCharacter(aiDictNameMap.get(aiUser.getCharacterCode()));
        output.setTag(aiDictNameMap.get(aiUser.getTagCode()));
        output.setRole(aiDictNameMap.get(aiUser.getRoleCode()));

        //扩展信息
        if (aiUserExt != null) {
            AiUserExtOutput aiUserExtOutput = BeanConver.copeBean(aiUserExt, AiUserExtOutput.class);
            aiUserExtOutput.setTimbreDict(timbreDictService.getTimbreDictByCode(aiUserExt.getDialogueTimbreCode()));
            aiUserExtOutput.setImageStyleDict(imageStyleDictService.getImageStyleDictByCode(aiUserExt.getImageStyleCode()));
            output.setAiUserExt(aiUserExtOutput);
        }
        return output;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setHomeImageUrl(Long aiId, String homeImageUrl) {
        update(Wrappers.<AiUser>lambdaUpdate().set(AiUser::getHomeImageUrl, homeImageUrl).eq(AiUser::getAiId, aiId));
    }


    @Override
    public void editAiHeadImg(Long userId, EditAiHeadImgInput input) {
        log.error("editAiHeadImg==UserInfoEditInput==> {}", JSONObject.toJSON(input));
        if (StringUtils.isNotEmpty(input.getUserHead())) {
            Long aiId = input.getAiId();
            AiUser aiUser = aiUserSearchService.getAiUserByAiId(aiId);
            ToastResultCode.AI_USER_NOT_EXIST.check(aiUser == null);
            //权限判断,非主人不能修改
            ToastResultCode.SYS_PERMISSION_DENIED.check(aiUser.getUserId() != null && !aiUser.getUserId().equals(userId));
            //判断头像地址是不是符合要求的
            ToastResultCode.SYS_PARAMETERS_VALIDATE_EXCEPTION.check(!RegexUtil.isOssStartUrl(input.getUserHead()));
            //判断头像是否有变更
            Boolean bl = ((StringUtils.isEmpty(aiUser.getHeadImg()) && !StringUtils.isEmpty(input.getUserHead()))
                    || (StringUtils.isNotEmpty(aiUser.getHeadImg()) && StringUtils.isNotEmpty(input.getUserHead()) && !aiUser.getHeadImg().equals(input.getUserHead())));
            if (bl) {
                //更新数据库用户信息
                update(Wrappers.<AiUser>lambdaUpdate().set(AiUser::getHeadImg, input.getUserHead()).eq(AiUser::getAiId, aiId));
                //发送MQ消息进行IM基础信息同步
                AiImInfoPayload aiImInfoPayload = new AiImInfoPayload();
                aiImInfoPayload.setAiId(aiId);
                aiImInfoPayload.setOptType(AiImInfoPayload.OptType.UPDATE);
                commonSendMqService.aiImInfoSendMq(aiImInfoPayload);
            }
        }
    }
}