package com.backendsys.service.Ai;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.backendsys.aspect.HttpRequestAspect;
import com.backendsys.modules.common.config.security.entity.SecurityUserInfo;
import com.backendsys.modules.common.config.security.utils.SecurityUtil;
import com.backendsys.modules.common.config.security.utils.TokenUtil;
import com.backendsys.entity.Ai.AiChatDTO;
import com.backendsys.mapper.Ai.AiChatHistoryMapper;
import com.backendsys.mapper.Ai.AiChatMapper;
import com.backendsys.mapper.System.SysUserMapper;
import com.backendsys.entity.Ai.AiChatHistoryDTO;
import com.backendsys.modules.sse.utils.SseUtil;
import com.backendsys.utils.response.PageInfoResult;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.SSEResponseModel;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.hunyuan.v20230901.HunyuanClient;

import com.tencentcloudapi.hunyuan.v20230901.models.ChatStdRequest;
import com.tencentcloudapi.hunyuan.v20230901.models.ChatStdResponse;

import com.tencentcloudapi.hunyuan.v20230901.models.Message;
import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@RequiredArgsConstructor
public class AiChatServiceImpl implements AiChatService {

    @Value("${tencent.hunyuan.secret-id}")
    private String SECRET_ID;
    @Value("${tencent.hunyuan.secret-key}")
    private String SECRET_KEY;
    @Value("${tencent.hunyuan.region}")
    private String REGION;

    @Value("${spring.application.name}")
    private String APPLICATION_NAME;
    @Autowired
    private SseUtil sseUtil;

//    @Autowired
//    private TokenUtil tokenUtil;

    private final SimpMessagingTemplate messagingTemplate;

    // -----------------------------------------------------------

//    @Autowired
//    private HttpRequestAspect httpRequestAspect;

    @Autowired
    private AiChatMapper aiChatMapper;

    @Autowired
    private AiChatHistoryMapper aiChatHistoryMapper;

//    @Autowired
//    private SysUserMapper sysUserMapper;

    /**
     * 查询 列表
     */
    public Map<String, Object> queryAiChatList(Integer pageNum, Integer pageSize, AiChatDTO aiChatDTO) {
        // 分页查询
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
            PageHelper.getLocalPage().setPageSizeZero(true);
        }
        // 分页输出 (自定义)
        List<Map<String, Object>> list = aiChatMapper.queryAiChatList(aiChatDTO);
        PageInfoResult pageInfoResult = new PageInfoResult(list);
        return pageInfoResult.toMap();
    }



    /**
     * 格式化 AI 回复内容的 实体类
     * 【腾讯云-混元大模型】 https://cloud.tencent.com/document/api/1729/101836
     */
    private AiChatDTO receiveAiChatDTO(AiChatDTO aiChatDTO) {



        // [查询] 自身 UserId (并加入)
        Long user_id = aiChatDTO.getUser_id();
        String history_code = aiChatDTO.getHistory_code();

        /**
         * 使用 Webstock 将 AI回复的内容 发送回给自己
         */
        SecurityUserInfo userInfo = SecurityUtil.getUserInfo();
        String receiver = userInfo.getUsername();

//        // 获得我的用户名
//        Claims loginUserInfo = tokenUtil.getRedisTokenInfo();
//        String receiver = (String) loginUserInfo.get("username");



        // [发送/接收] 内容
        String sendContent = aiChatDTO.getContent();
        String receiveContent = "";
        String receiveRobotCode = "";

        try {

            Credential cred = new Credential(SECRET_ID, SECRET_KEY);

            ClientProfile clientProfile = new ClientProfile();
            HunyuanClient client = new HunyuanClient(cred, REGION, clientProfile);


            // 根据 history_code 查询全部的对话历史记录
            AiChatDTO aiChatDTO_by_history = new AiChatDTO();
            aiChatDTO_by_history.setHistory_code(history_code);
            List<Map<String, Object>> aiChat_list_by_history = aiChatMapper.queryAiChatList(aiChatDTO_by_history);

            // 遍历历史记录，将历史记录赋值到 要提交的内容数组上
            // https://cloud.tencent.com/document/product/1729/101836
            // (2. 输入参数 Messages.N 聊天上下文信息。)
            Message[] msgList = new Message[aiChat_list_by_history.size()];
            if (!aiChat_list_by_history.isEmpty()) {
                for (int i = 0; i < aiChat_list_by_history.size(); i++) {
                    Map<String, Object> aiChat = aiChat_list_by_history.get(i);
                    Message msg = new Message();
                    msg.setRole((String) aiChat.get("role"));
                    msg.setContent((String) aiChat.get("content"));
                    msgList[i] = msg;
                }
            }

//            // 追加新的 对话内容 (当前的)
//            Message additionalMsg = new Message();
//            additionalMsg.setRole("user");
//            additionalMsg.setContent(sendContent);
//            // [Hutool] 追加内容
//            msgList = ArrayUtil.append(msgList, additionalMsg);

//            System.out.println("msgList:");
//            for (Message msg : msgList) {
//                System.out.println("Role: " + msg.getRole() + ", Content: " + msg.getContent());
//            }


//            // 发送对话 (高级版)
//            ChatProRequest req = new ChatProRequest();
//            req.setMessages(msgList);
//            ChatProResponse resp = client.ChatPro(req);

            // 发送对话 (标准版)
            ChatStdRequest req = new ChatStdRequest();
            req.setMessages(msgList);
            ChatStdResponse resp = client.ChatStd(req);

//            System.out.println(resp);

            Gson gson = new GsonBuilder().create();
            for (SSEResponseModel.SSE e : resp) {

//                 System.out.println(e.Data);
                /**
                 *
                 * .Data:
                 *  {"Note":"以上内容为AI生成，不代表开发者立场，请勿删除或修改本标记","Choices":[{"FinishReason":"","Delta":{"Role":"assistant","Content":"当然"}}],"Created":1709618061,"Id":"e73c0a71-5c98-4893-ba90-ad5056d5871a","Usage":{"PromptTokens":7,"CompletionTokens":1,"TotalTokens":8}}
                 * e.Data:
                 *  {"Note":"以上内容为AI生成，不代表开发者立场，请勿删除或修改本标记","Choices":[{"FinishReason":"","Delta":{"Role":"assistant","Content":"可以"}}],"Created":1709618061,"Id":"e73c0a71-5c98-4893-ba90-ad5056d5871a","Usage":{"PromptTokens":7,"CompletionTokens":2,"TotalTokens":9}}
                 * e.Data:
                 *  {"Note":"以上内容为AI生成，不代表开发者立场，请勿删除或修改本标记","Choices":[{"FinishReason":"","Delta":{"Role":"assistant","Content":"，"}}],"Created":1709618061,"Id":"e73c0a71-5c98-4893-ba90-ad5056d5871a","Usage":{"PromptTokens":7,"CompletionTokens":3,"TotalTokens":10}}
                 * e.Data:
                 */
                JSONObject dataObject = JSONUtil.parseObj(e.Data);

                // [Webstock] 将消息推送到前台
                messagingTemplate.convertAndSendToUser(receiver, "/queue/ai-chating", e.Data);

                // [SSE] 发送消息
                sseUtil.send(user_id, e.Data);

                receiveRobotCode = dataObject.getStr("Id");
                JSONArray choicesArray = dataObject.getJSONArray("Choices");
                if (choicesArray != null && choicesArray.size() > 0) {
                    JSONObject firstChoice = choicesArray.getJSONObject(0);
                    JSONObject deltaObject = firstChoice.getJSONObject("Delta");
                    receiveContent += deltaObject.getStr("Content");
                }

            }

        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }

        AiChatDTO robotChatDTO = new AiChatDTO();
        robotChatDTO.setUser_id(user_id);
        robotChatDTO.setHistory_code(history_code);
        robotChatDTO.setRobot_code(receiveRobotCode);
        robotChatDTO.setRole("assistant");
        robotChatDTO.setContent(receiveContent);

        return robotChatDTO;
    }

    /**
     * 欺骗的AI回复内容
     */
    private AiChatDTO cheatAiChatDTO(AiChatDTO aiChatDTO, String content) {

        SecurityUserInfo userInfo = SecurityUtil.getUserInfo();
        String receiver = userInfo.getUsername();

//        // 获得我的用户名
//        Claims loginUserInfo = tokenUtil.getRedisTokenInfo();
//        String receiver = (String) loginUserInfo.get("username");

        // [查询] 自身 UserId (并加入)
        Long user_id = aiChatDTO.getUser_id();
        String history_code = aiChatDTO.getHistory_code();

        AiChatDTO robotChatDTO = new AiChatDTO();
        robotChatDTO.setUser_id(user_id);
        robotChatDTO.setHistory_code(history_code);
        robotChatDTO.setRobot_code("Cheat");
        robotChatDTO.setRole("assistant");
        robotChatDTO.setContent(content);

        String uuid = String.valueOf(UUID.randomUUID());
        long timestamp = DateUtil.currentSeconds();
        String data = "{\"Note\":\"Cheat Content\",\"Choices\":[{\"FinishReason\":\"stop\",\"Delta\":{\"Role\":\"assistant\",\"Content\":\"" + content + "\"}}],\"Created\":" + timestamp + ",\"Id\":\"" + uuid + "\",\"Usage\":{\"PromptTokens\":1,\"CompletionTokens\":1,\"TotalTokens\":1}}";

        // [Webstock] 将消息推送到前台
        messagingTemplate.convertAndSendToUser(receiver, "/queue/ai-chating", data);

        return robotChatDTO;
    }


    /**
     * 创建
     * 
     * 传参有几种情况：
     * - { content }：[新增] 对话内容；[新增] 历史记录；
     * - { content, history_code }：在对应的 {历史记录} 下新增对话内容；
     */
    @Override
    @Transactional
    public Map<String, Object> insertAiChat(AiChatDTO aiChatDTO) {

        String[] cheatKeyword = {"你是谁","你是什么","介绍一下自己"};

        // [查询] 自身 UserId (并加入)
//        Long user_id = httpRequestAspect.getUserId();
//        aiChatDTO.setUser_id(user_id);

        // 添加 当前用户名/对话角色
        SecurityUserInfo userInfo = SecurityUtil.getUserInfo();
        aiChatDTO.setUser_id(userInfo.getUser_id());
        aiChatDTO.setUser_nickname(userInfo.getUsername());
        aiChatDTO.setRole("user");

//        // [查询] 自身 用户信息 (并加入)
//        Map<String, Object> userDetail = sysUserMapper.queryUserDetail(user_id);
//        aiChatDTO.setUser_nickname((String) userDetail.get("nickname"));
//        aiChatDTO.setUser_avatar((String) userDetail.get("avatar"));
//        aiChatDTO.setRole("user");

        // [Create] 如果参数中没有带 { history_code } 时，则在新增的同时创建 chat_history表 记录
        String history_code = aiChatDTO.getHistory_code();
        // 当 { history_code} 为空时
        if (history_code == null || history_code == "") {
            
            // 生成新的 history_code
            history_code = String.valueOf(UUID.randomUUID());
            aiChatDTO.setHistory_code(history_code);

            // -- [新增] 历史记录 -------------------------------------------------------
            AiChatHistoryDTO aiChatHistoryDTO = new AiChatHistoryDTO();
//            aiChatHistoryDTO.setUser_id(user_id);
            aiChatHistoryDTO.setUser_id(userInfo.getUser_id());
            aiChatHistoryDTO.setHistory_code(history_code);

            // 最后一次发送的内容 (超过 255 字符时截取)
            String content = aiChatDTO.getContent();
            if (content.length() > 255) content = content.substring(0, 255);
            aiChatHistoryDTO.setLast_content(content);
            // -------------------------------------------------------------------------

            // [插入] 新的历史记录
            aiChatHistoryMapper.insertAiChatHistory(aiChatHistoryDTO);

            // [插入] 新的对话 (用户)
            aiChatMapper.insertAiChat(aiChatDTO);

            // [插入] 新的对话 (机器人)
            AiChatDTO robotChatDTO = null;
            // 带着欺骗的
            if (StrUtil.containsAny(aiChatDTO.getContent(), cheatKeyword)) {
                robotChatDTO = cheatAiChatDTO(aiChatDTO, "嗨，我是你的AI人工智能助手。无论你有什么问题或需要帮助，我都在这里为你服务。让我们一起探索今天你需要解决的吧！");
            } else {
                robotChatDTO = receiveAiChatDTO(aiChatDTO);
            }
            aiChatMapper.insertAiChat(robotChatDTO);

        } else {

            // 当 { history_code } 不为空时

            // 判断历史记录是否存在
            AiChatHistoryDTO chatHistoryDTO = new AiChatHistoryDTO();
            chatHistoryDTO.setHistory_code(history_code);
            // 查询
            List<Map<String, Object>> chatHistoryList = aiChatHistoryMapper.queryAiChatHistory(chatHistoryDTO);
            // 当历史记录不存在时，创建新的历史记录
            if (chatHistoryList.isEmpty()) {
                System.out.println("chatHistoryList is Empty!");
                // -- [新增] 历史记录 -------------------------------------------------------
                AiChatHistoryDTO aiChatHistoryDTO = new AiChatHistoryDTO();
//                aiChatHistoryDTO.setUser_id(user_id);
                aiChatHistoryDTO.setUser_id(userInfo.getUser_id());
                aiChatHistoryDTO.setHistory_code(history_code);

                // 最后一次发送的内容 (超过 255 字符时截取)
                String content = aiChatDTO.getContent();
                if (content.length() > 255) content = content.substring(0, 255);
                aiChatHistoryDTO.setLast_content(content);
                
                // [插入] 新的对话历史记录
                aiChatHistoryMapper.insertAiChatHistory(aiChatHistoryDTO);
                // -------------------------------------------------------------------------
            }

            // [已存在历史记录]

            // [插入] 新的对话 (用户)
            aiChatMapper.insertAiChat(aiChatDTO);

            // [插入] 新的对话 (机器人)
            AiChatDTO robotChatDTO = null;
            // 带着欺骗的
            if (StrUtil.containsAny(aiChatDTO.getContent(), cheatKeyword)) {
                robotChatDTO = cheatAiChatDTO(aiChatDTO, "嗨，我是你的AI人工智能助手。无论你有什么问题或需要帮助，我都在这里为你服务。让我们一起探索今天你需要解决的吧！");
            } else {
                robotChatDTO = receiveAiChatDTO(aiChatDTO);
            }
            aiChatMapper.insertAiChat(robotChatDTO);

        }

        return Map.of("history_code", history_code);
    }

    // /**
    //  * 更新
    //  */
    // @Override
    // @Transactional
    // public Map<String, Object> updateAiChat(AiChatDTO aiChatDTO) {
    //     aiChatMapper.updateAiChat(aiChatDTO);
    //     return Map.of("history_code", aiChatDTO.getHistory_code());
    // }

    /**
     * 删除
     */
    @Override
    @Transactional
    public Map<String, Object> deleteAiChat(AiChatDTO aiChatDTO) {
        aiChatMapper.deleteAiChat(aiChatDTO);
        return Map.of("history_code", aiChatDTO.getHistory_code());
    }
}
