package com.backendsys.modules.ai.chat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.backendsys.exception.CustException;
import com.backendsys.modules.ai.chat.dao.ChatDao;
import com.backendsys.modules.ai.chat.dao.ChatHistoryDao;
import com.backendsys.modules.ai.chat.entity.Chat;
import com.backendsys.modules.ai.chat.entity.ChatCompletionParam;
import com.backendsys.modules.ai.chat.entity.ChatHistory;
import com.backendsys.modules.ai.chat.entity.ChatResult;
import com.backendsys.modules.ai.chat.service.ChatService;
import com.backendsys.modules.common.config.redis.utils.RedisUtil;
import com.backendsys.modules.common.config.security.utils.SecurityUtil;
import com.backendsys.modules.sdk.deepseek.service.DeepSeekClient;
import com.backendsys.modules.sdk.deepseek.utils.OllamaUtil;
import com.backendsys.modules.sdk.tencentcloud.huanyuan.service.HunYuanClient;
import com.backendsys.utils.response.PageEntity;
import com.backendsys.utils.response.PageInfoResult;
import com.backendsys.utils.v2.PageUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private HunYuanClient hunYuanClient;
    @Autowired
    private DeepSeekClient deepSeekClient;
    @Autowired
    private OllamaUtil ollamaUtil;
    @Autowired
    private RedisUtil redisUtil;

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

    @Autowired
    private ChatDao chatDao;
    @Autowired
    private ChatHistoryDao chatHistoryDao;

    /**
     * 发起对话
     * - model: (HUNYUAN-混元, DEEPSEEK)
     */
    @Override
    public Map<String, Object> sendChat(Chat chat) {

        // 手动设置 SecurityContext
        SecurityContext context = SecurityContextHolder.getContext();
        SecurityContextHolder.setContext(context);

        Long user_id = SecurityUtil.getUserId();
        chat.setUser_id(user_id);
        chat.setRole("user");

        String model = chat.getModel();
        String model_version = chat.getModel_version();
        String tag = chat.getTag();
        String prompt = chat.getContent();

        if (("DEEPSEEK".equals(model)) && StrUtil.isEmpty(model_version)) {
            throw new CustException("请选择(Deepseek)模型版本");
        }

        // -- 是否首次创建 (如果历史记录code为空，即是首次创建) ---------------
        Boolean is_create = false;
        String history_code = chat.getHistory_code();
        if (StrUtil.isEmpty(history_code)) {
            is_create = true;
            // 首次创建，生成随机的 UUID
            history_code = UUID.randomUUID().toString();
            chat.setHistory_code(history_code);
        }

        // -- 对话历史记录 -----------------------------------------------
        if (is_create) {
            // 首次创建
            ChatHistory historyEntity = new ChatHistory();
            historyEntity.setHistory_code(history_code);
            historyEntity.setUser_id(user_id);
            historyEntity.setLast_prompt(prompt);

            // [创建]
            chatHistoryDao.insert(historyEntity);
        } else {
            // 查询历史对话是否存在
            LambdaQueryWrapper<ChatHistory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ChatHistory::getDel_flag, -1);
            wrapper.eq(ChatHistory::getHistory_code, history_code);
            ChatHistory historyDetail = chatHistoryDao.selectOne(wrapper);
            if (historyDetail == null) throw new CustException("history_code 不存在，请重新创建");

            // [更新] 最后一次提交的内容
            historyDetail.setLast_prompt(prompt);
            chatHistoryDao.updateById(historyDetail);
        }

        // -- 对话 -----------------------------------------------------


        // -- 创建一个对话缓存键值 (用于停止请求) ---------------------------
        String requestOfRedisKey = APPLICATION_NAME + "-chat-history-" + history_code;
        redisUtil.setCacheObject(requestOfRedisKey, 1);
//
//        // -- 是否对话进行中 ---------------------------------------------
//        if (ObjectUtil.isNotEmpty(redisUtil.getCacheObject(requestOfRedisKey))) {
//            throw new CustException("请等待对话结束");
//        }

        // 创建一个 CompletableFuture 来执行异步任务
        String final_history_code = history_code;
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            try {

                // [DB] 查询对话历史记录 (用于对话上下文)
                // - 按 [创建时间]、[Id] 降序，最新的在最后面
                // - 排除 [THINK-思考] 的内容，但允许 [Null]
                List<Chat> chatList = chatDao.selectList(
                    new LambdaQueryWrapper<Chat>()
                        .eq(Chat::getDel_flag, -1)
                        .eq(Chat::getHistory_code, final_history_code)
                        .and(wrapper -> wrapper
                            .ne(Chat::getContent_type, "THINK")
                            .or()
                            .isNull(Chat::getContent_type))
                        .orderByDesc(Chat::getCreate_time)
                        .orderByDesc(Chat::getId)
                );

                // [INSERT][提问] 内容
                Chat userChat = new Chat();
                BeanUtil.copyProperties(chat, userChat);
                chatDao.insert(userChat);

                ChatResult chatResult = null;
                // -- [Deepseek R1] -------------------------------------------------------

                // [Param] 对话参数
                ChatCompletionParam chatCompletionParam = new ChatCompletionParam();
                chatCompletionParam.setUser_id(user_id);
                chatCompletionParam.setModel(model_version);
                chatCompletionParam.setPrompt(prompt);
                chatCompletionParam.setHistory_code(final_history_code);
                chatCompletionParam.setChatList(chatList);
                chatCompletionParam.setInternet(chat.getInternet());

                System.out.println(chatCompletionParam);

                if ("OLLAMA".equals(tag)) {
                    chatResult = ollamaUtil.chatCompletion(chatCompletionParam);
                }
                if ("API".equals(tag)) {
                    // -- [Deepseek Api] ------------------------------------------------------
                    if ("DEEPSEEK_API".equals(model)) {
                        // [DeepSeek] 发起对话
                        chatResult = deepSeekClient.chatCompletion(chatCompletionParam);
                    }
                    // -- [腾讯混元大模型] -------------------------------------------------------
                    if ("HUNYUAN".equals(model)) {
                        chatResult = hunYuanClient.chatCompletion(chatCompletionParam);
                    }
                    // ------------------------------------------------------------------------
                }

                if (chatResult != null) {

                    // [顺序1][INSERT][引用] SYSTEM
                    String internetContent = chatResult.getInternet_content();
                    if (StrUtil.isNotEmpty(internetContent)) {
                        //
                        Chat internetChat = new Chat();
                        BeanUtil.copyProperties(chat, internetChat);
                        //
                        internetChat.setRole("system");
                        internetChat.setContent_type("SEARCH");
                        internetChat.setContent(internetContent);
                        internetChat.setDuration(chatResult.getInternet_duration());
                        chatDao.insert(internetChat);
                    }

                    // [顺序2][INSERT][思考] THINK
                    String reasoningContent = chatResult.getReasoning_content();
                    if (StrUtil.isNotEmpty(reasoningContent)) {
                        //
                        Chat thinkChat = new Chat();
                        BeanUtil.copyProperties(chat, thinkChat);
                        //
                        thinkChat.setRole("assistant");
                        thinkChat.setContent_type("THINK");
                        thinkChat.setContent(reasoningContent);
                        thinkChat.setDuration(chatResult.getReasoning_duration());
                        chatDao.insert(thinkChat);
                    }

                    // [顺序3][INSERT][回复] REPLY
                    String content = chatResult.getContent();
                    if (StrUtil.isNotEmpty(content)) {
                        //
                        Chat replyChat = new Chat();
                        BeanUtil.copyProperties(chat, replyChat);
                        //
                        replyChat.setRole("assistant");
                        replyChat.setContent_type("REPLY");
                        replyChat.setContent(content);
                        replyChat.setDuration(chatResult.getContent_duration());
                        chatDao.insert(replyChat);
                    }

                } else {
                    System.out.println("chatResult 结果为空!");
                }


            } catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                // 流程结束后，删除锁
                redisUtil.delete(requestOfRedisKey);
            }
        });
        // ------------------------------------------------------------

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

    }


    /**
     * 中止对话
     */
    @Override
    public Map<String, Object> abortChat(Chat chat) {
        String history_code = chat.getHistory_code();
        String requestOfRedisKey = APPLICATION_NAME + "-chat-history-" + history_code;
        redisUtil.delete(requestOfRedisKey);
        return Map.of("history_code", history_code);
    }

    /**
     * 获取我的对话列表 (升序, 最新的在最后面出现)
     */
    @Override
    public PageEntity selectChatList(Chat chat) {

        ChatHistory chatHistory = chatHistoryDao.selectOne(
            new LambdaQueryWrapper<ChatHistory>()
                .eq(ChatHistory::getUser_id, chat.getUser_id())
                .eq(ChatHistory::getHistory_code, chat.getHistory_code())
                .eq(ChatHistory::getDel_flag, chat.getDel_flag())
        );
        if (chatHistory == null) throw new CustException("对话历史不存在");

        PageUtils.startPage();  // 分页
        List<Chat> list = chatDao.selectChatList(chat);
        return new PageInfoResult(list).toEntity();
    }


    /**
     * 删除我的对话 (软删除)
     */
    @Override
    public Map<String, Object> deleteChat(Chat chat) {

        // [软删除] 删除对话
        chat.setDel_flag(1);

        chatDao.update(chat, new LambdaQueryWrapper<Chat>()
            .eq(Chat::getUser_id, chat.getUser_id())
            .eq(Chat::getDel_flag, -1)
            .eq(Chat::getHistory_code, chat.getHistory_code())
        );

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

    /**
     * 删除我的对话 (软删除)(单条)
     */
    @Override
    public Map<String, Object> deleteChatOne(Chat chat) {

        // [软删除] 删除对话
        chat.setDel_flag(1);

        chatDao.update(chat, new LambdaQueryWrapper<Chat>()
            .eq(Chat::getUser_id, chat.getUser_id())
            .eq(Chat::getDel_flag, -1)
            .eq(Chat::getId, chat.getId())
        );
        System.out.println(chat);

        return Map.of("id", chat.getId());
    }


}
