package org.dromara.chat.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.ai.domain.dto.AiChatRequest;
import org.dromara.ai.domain.dto.AiChatResponse;
import org.dromara.ai.service.AiChatService;
import org.dromara.chat.domain.bo.ChatMessageBo;
import org.dromara.chat.domain.bo.ChatSessionBo;
import org.dromara.chat.domain.vo.ChatMessageVo;
import org.dromara.chat.domain.vo.ChatSessionVo;
import org.dromara.chat.service.AiKnowledgeChatService;
import org.dromara.chat.service.ChatMessageService;
import org.dromara.chat.service.ChatSessionService;
import org.dromara.knowledge.domain.vo.KnowledgeInfoVo;
import org.dromara.knowledge.domain.vo.KnowledgeSearchResultVo;
import org.dromara.knowledge.service.KnowledgeInfoService;
import org.dromara.knowledge.service.KnowledgeVectorService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 知识库聊天服务实现
 *
 * @author pengles
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class AiKnowledgeChatServiceImpl implements AiKnowledgeChatService {

    private final ChatSessionService chatSessionService;
    private final ChatMessageService chatMessageService;
    private final KnowledgeInfoService knowledgeInfoService;
    private final KnowledgeVectorService knowledgeVectorService;
    private final AiChatService aiChatService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatMessageVo chatWithKnowledge(Long sessionId, Long userId, String question, Long knowledgeId, String modelName) {
        // 验证会话是否存在
        ChatSessionVo session = chatSessionService.queryById(sessionId);
        if (ObjectUtil.isNull(session)) {
            throw new RuntimeException("会话不存在");
        }

        // 验证知识库是否存在
        KnowledgeInfoVo knowledge = knowledgeInfoService.queryById(knowledgeId);
        if (ObjectUtil.isNull(knowledge)) {
            throw new RuntimeException("知识库不存在");
        }

        // 保存用户问题
        ChatMessageBo userMessageBo = new ChatMessageBo();
        userMessageBo.setSessionId(sessionId);
        userMessageBo.setUserId(userId);
        userMessageBo.setMessageType("text");
        userMessageBo.setContent(question);
        userMessageBo.setRole("user");
        userMessageBo.setModelName(modelName);
        userMessageBo.setCreateTime(new Date());
        chatMessageService.insertByBo(userMessageBo);

        try {
            AiChatRequest req = new AiChatRequest()
                .setUserId(String.valueOf(userId))
                .setSessionId(String.valueOf(sessionId))
                .setModel(modelName)
                .setEnableKnowledge(true)
                .setKnowledgeId(String.valueOf(knowledgeId))
                .setKnowledgeLimit(5)
                .setKnowledgeThreshold(0.7)
                .setMessages(java.util.List.of(
                    new AiChatRequest.AiMessage().setRole("user").setContent(question)
                ));

            AiChatResponse resp = aiChatService.chat(req);
            String aiAnswer = "";
            if (resp != null && resp.getChoices() != null && !resp.getChoices().isEmpty()) {
                AiChatRequest.AiMessage msg = resp.getChoices().get(0).getMessage();
                if (msg != null && StrUtil.isNotBlank(msg.getContent())) {
                    aiAnswer = msg.getContent();
                }
            }
            if (StrUtil.isBlank(aiAnswer)) {
                throw new RuntimeException("AI服务返回空回答");
            }

            // 保存AI回复
            ChatMessageBo aiMessageBo = new ChatMessageBo();
            aiMessageBo.setSessionId(sessionId);
            aiMessageBo.setUserId(userId);
            aiMessageBo.setMessageType("text");
            aiMessageBo.setContent(aiAnswer);
            aiMessageBo.setRole("assistant");
            aiMessageBo.setModelName(modelName);
            aiMessageBo.setTotalTokens(0L); // 简化版本不统计token
            aiMessageBo.setDeductCost(BigDecimal.ZERO); // 简化版本不计费
            aiMessageBo.setCreateTime(new Date());
            chatMessageService.insertByBo(aiMessageBo);

            return chatMessageService.queryById(aiMessageBo.getId());

        } catch (Exception e) {
            log.error("知识库聊天失败 - 用户: {}, 会话: {}, 知识库: {}", userId, sessionId, knowledgeId, e);

            // 保存错误回复
            ChatMessageBo errorMessageBo = new ChatMessageBo();
            errorMessageBo.setSessionId(sessionId);
            errorMessageBo.setUserId(userId);
            errorMessageBo.setMessageType("text");
            errorMessageBo.setContent("抱歉，AI服务暂时不可用，请稍后重试。");
            errorMessageBo.setRole("assistant");
            errorMessageBo.setModelName(modelName);
            errorMessageBo.setCreateTime(new Date());
            chatMessageService.insertByBo(errorMessageBo);

            return chatMessageService.queryById(errorMessageBo.getId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatSessionVo createKnowledgeSession(Long userId, Long knowledgeId, String sessionTitle) {
        // 验证知识库是否存在
        KnowledgeInfoVo knowledge = knowledgeInfoService.queryById(knowledgeId);
        if (ObjectUtil.isNull(knowledge)) {
            throw new RuntimeException("知识库不存在");
        }

        // 如果没有提供标题，使用知识库名称作为默认标题
        if (StrUtil.isBlank(sessionTitle)) {
            sessionTitle = "基于" + knowledge.getKnowledgeName() + "的对话";
        }

        // 创建会话
        ChatSessionBo sessionBo = new ChatSessionBo();
        sessionBo.setUserId(userId);
        sessionBo.setSessionTitle(sessionTitle);
        sessionBo.setSessionContent("知识库ID: " + knowledgeId);
        sessionBo.setCreateTime(new Date());
        chatSessionService.insertByBo(sessionBo);

        return chatSessionService.queryById(sessionBo.getId());
    }

    @Override
    public List<String> searchKnowledgeContent(Long knowledgeId, String query, Integer limit) {
        try {
            log.info("搜索知识库内容 - 知识库: {}, 查询: {}, 限制: {}", knowledgeId, query, limit);
            List<KnowledgeSearchResultVo> searchResults = knowledgeVectorService.vectorSimilaritySearch(
                    String.valueOf(knowledgeId), query, "default", limit != null ? limit : 5, 0.7
            );
            return searchResults.stream().map(KnowledgeSearchResultVo::getContent).toList();
        } catch (Exception e) {
            log.error("搜索知识库内容失败 - 知识库: {}, 查询: {}", knowledgeId, query, e);
            return Collections.emptyList();
        }
    }

    @Override
    public String buildKnowledgeContext(Long knowledgeId, String question) {
        // 搜索相关知识库内容
        List<String> relevantContent = searchKnowledgeContent(knowledgeId, question, 3);

        StringBuilder context = new StringBuilder();
        context.append("以下是相关的知识库内容:\n\n");

        for (int i = 0; i < relevantContent.size(); i++) {
            context.append("参考资料 ").append(i + 1).append(": ");
            context.append(relevantContent.get(i)).append("\n\n");
        }

        return context.toString();
    }

    @Override
    public List<ChatMessageVo> getKnowledgeChatHistory(Long sessionId, Integer limit) {
        // 获取会话的聊天历史
        List<ChatMessageVo> messages = chatMessageService.queryListBySessionId(sessionId);

        // 如果指定了限制数量，返回最近的消息
        if (limit != null && limit > 0 && messages.size() > limit) {
            return messages.subList(Math.max(0, messages.size() - limit), messages.size());
        }

        return messages;
    }


}
