package org.dromara.ai.service;

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.provider.AiProvider;
import org.dromara.ai.provider.AiProviderManager;
import org.dromara.knowledge.domain.vo.KnowledgeSearchResultVo;
import org.dromara.knowledge.service.KnowledgeVectorService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * AI聊天服务
 * 提供统一的AI聊天接口，支持同步、异步和流式对话模式
 *
 * @author pengles
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AiChatService {

    private final AiProviderManager providerManager;
    private final KnowledgeVectorService knowledgeVectorService;
    private final org.dromara.ai.mcp.McpIntegrationService mcpIntegrationService;
    private final AiChatHistoryService chatHistoryService;

    /**
     * 同步聊天对话
     *
     * @param request 聊天请求
     * @return 聊天响应
     */
    public AiChatResponse chat(AiChatRequest request) {
        log.info("开始AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());

        try {
            // 预处理请求
            preprocessRequest(request);
            mcpIntegrationService.enrichMessages(request);

            // 知识库增强
            if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                enhanceWithKnowledge(request);
            }

            // 执行聊天
            AiChatResponse response = providerManager.chat(request);

            // 后处理响应
            postprocessResponse(response, request);

            // 保存聊天历史
            if (StringUtils.hasText(request.getSessionId())) {
                chatHistoryService.saveHistory(request.getSessionId(), request, response);
            }

            log.info("AI聊天对话完成 - 用户: {}, 响应时间: {}ms",
                    request.getUserId(), response.getResponseTime());

            return response;

        } catch (Exception e) {
            log.error("AI聊天对话失败 - 用户: {}", request.getUserId(), e);
            return createErrorResponse(e, request);
        }
    }

    /**
     * 异步聊天对话
     *
     * @param request 聊天请求
     * @return 异步聊天响应
     */
    public CompletableFuture<AiChatResponse> chatAsync(AiChatRequest request) {
        log.info("开始异步AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());

        return CompletableFuture.supplyAsync(() -> {
            try {
                // 预处理请求
                preprocessRequest(request);
                mcpIntegrationService.enrichMessages(request);

                // 知识库增强
                if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                    enhanceWithKnowledge(request);
                }

                return request;

            } catch (Exception e) {
                log.error("异步AI聊天预处理失败 - 用户: {}", request.getUserId(), e);
                throw new RuntimeException(e);
            }
        }).thenCompose(preprocessedRequest -> {
            return providerManager.chatAsync(preprocessedRequest)
                    .thenApply(response -> {
                        // 后处理响应
                        postprocessResponse(response, preprocessedRequest);

                        // 保存聊天历史
                        if (org.springframework.util.StringUtils.hasText(preprocessedRequest.getSessionId())) {
                            chatHistoryService.saveHistory(preprocessedRequest.getSessionId(), preprocessedRequest, response);
                        }

                        log.info("异步AI聊天对话完成 - 用户: {}, 响应时间: {}ms",
                                preprocessedRequest.getUserId(), response.getResponseTime());

                        return response;
                    });
        }).exceptionally(throwable -> {
            log.error("异步AI聊天对话失败 - 用户: {}", request.getUserId(), throwable);
            return createErrorResponse(throwable, request);
        });
    }

    /**
     * 流式聊天对话
     *
     * @param request  聊天请求
     * @param callback 流式回调
     */
    public void chatStream(AiChatRequest request, StreamCallback callback) {
        log.info("开始流式AI聊天对话 - 用户: {}, 模型: {}", request.getUserId(), request.getModel());

        try {
            // 预处理请求
            preprocessRequest(request);
            mcpIntegrationService.enrichMessages(request);

            // 知识库增强
            if (Boolean.TRUE.equals(request.getEnableKnowledge()) && StringUtils.hasText(request.getKnowledgeId())) {
                enhanceWithKnowledge(request);
            }

            // 执行流式聊天
            providerManager.chatStream(request, new AiProvider.StreamCallback() {
                @Override
                public void onChunk(String chunk) {
                    callback.onChunk(chunk);
                }

                @Override
                public void onComplete(AiChatResponse response) {
                    // 后处理响应
                    postprocessResponse(response, request);

                    // 保存聊天历史
                    if (StringUtils.hasText(request.getSessionId())) {
                        chatHistoryService.saveHistory(request.getSessionId(), request, response);
                    }

                    log.info("流式AI聊天对话完成 - 用户: {}, 响应时间: {}ms",
                            request.getUserId(), response.getResponseTime());

                    callback.onComplete(response);
                }

                @Override
                public void onError(Throwable error) {
                    log.error("流式AI聊天对话失败 - 用户: {}", request.getUserId(), error);
                    callback.onError(error);
                }
            });

        } catch (Exception e) {
            log.error("流式AI聊天对话启动失败 - 用户: {}", request.getUserId(), e);
            callback.onError(e);
        }
    }

    /**
     * 批量聊天对话
     *
     * @param requests 聊天请求列表
     * @return 聊天响应列表
     */
    public List<CompletableFuture<AiChatResponse>> chatBatch(List<AiChatRequest> requests) {
        log.info("开始批量AI聊天对话 - 请求数量: {}", requests.size());

        return requests.stream()
                .map(this::chatAsync)
                .collect(Collectors.toList());
    }

    /**
     * 等待所有批量聊天完成
     *
     * @param futures 异步响应列表
     * @return 聊天响应列表
     */
    public List<AiChatResponse> waitForBatchCompletion(List<CompletableFuture<AiChatResponse>> futures) {
        CompletableFuture<Void> allOf = CompletableFuture.allOf(
                futures.toArray(new CompletableFuture[0])
        );

        return allOf.thenApply(v ->
                futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList())
        ).join();
    }

    /**
     * 预处理请求
     *
     * @param request 聊天请求
     */
    private void preprocessRequest(AiChatRequest request) {
        // 设置默认值
        if (request.getTemperature() == null) {
            request.setTemperature(0.7);
        }
        if (request.getMaxTokens() == null) {
            request.setMaxTokens(2000);
        }
        if (request.getStream() == null) {
            request.setStream(false);
        }

        // 验证请求参数
        validateRequest(request);

        // 记录请求日志
        log.debug("预处理AI聊天请求 - 用户: {}, 消息数: {}",
                request.getUserId(), request.getMessages() != null ? request.getMessages().size() : 0);
    }

    /**
     * 验证请求参数
     *
     * @param request 聊天请求
     */
    private void validateRequest(AiChatRequest request) {
        if (request.getMessages() == null || request.getMessages().isEmpty()) {
            throw new IllegalArgumentException("消息列表不能为空");
        }

        if (request.getTemperature() != null && (request.getTemperature() < 0 || request.getTemperature() > 2)) {
            throw new IllegalArgumentException("温度参数必须在0-2之间");
        }

        if (request.getTopP() != null && (request.getTopP() < 0 || request.getTopP() > 1)) {
            throw new IllegalArgumentException("Top-p参数必须在0-1之间");
        }

        if (request.getMaxTokens() != null && request.getMaxTokens() <= 0) {
            throw new IllegalArgumentException("最大token数必须大于0");
        }
    }

    /**
     * 知识库增强
     *
     * @param request 聊天请求
     */
    private void enhanceWithKnowledge(AiChatRequest request) {
        try {
            // 获取最后一条用户消息
            String userMessage = request.getMessages().stream()
                    .filter(msg -> "user".equals(msg.getRole()))
                    .reduce((first, second) -> second)
                    .map(AiChatRequest.AiMessage::getContent)
                    .orElse("");

            if (StringUtils.hasText(userMessage)) {
                // 执行知识库检索
                List<KnowledgeSearchResultVo> searchResults = knowledgeVectorService.vectorSimilaritySearch(
                        request.getKnowledgeId(),
                        userMessage,
                        request.getModel(),
                        request.getKnowledgeLimit() != null ? request.getKnowledgeLimit() : 5,
                        request.getKnowledgeThreshold() != null ? request.getKnowledgeThreshold() : 0.7
                );

                if (!searchResults.isEmpty()) {
                    // 构建知识库上下文
                    StringBuilder contextBuilder = new StringBuilder();
                    contextBuilder.append("以下是相关的知识库信息，请参考这些信息回答用户问题：\n\n");

                    for (int i = 0; i < searchResults.size(); i++) {
                        KnowledgeSearchResultVo result = searchResults.get(i);
                        contextBuilder.append(String.format("[知识%d] %s\n", i + 1, result.getContent()));
                    }

                    contextBuilder.append("\n请基于以上知识库信息回答用户问题。如果知识库中没有相关信息，请明确说明。\n\n");

                    // 在消息列表开头添加系统消息
                    AiChatRequest.AiMessage systemMessage = new AiChatRequest.AiMessage()
                            .setRole("system")
                            .setContent(contextBuilder.toString());

                    List<AiChatRequest.AiMessage> enhancedMessages = new ArrayList<>();
                    enhancedMessages.add(systemMessage);
                    enhancedMessages.addAll(request.getMessages());

                    request.setMessages(enhancedMessages);

                    log.debug("知识库增强完成 - 检索到{}条相关信息", searchResults.size());
                }
            }

        } catch (Exception e) {
            log.warn("知识库增强失败，继续使用原始请求", e);
        }
    }

    /**
     * 后处理响应
     *
     * @param response 聊天响应
     * @param request  原始请求
     */
    private void postprocessResponse(AiChatResponse response, AiChatRequest request) {
        // 设置用户信息
        if (response.getExtra() == null) {
            response.setExtra(new java.util.HashMap<>());
        }
        response.getExtra().put("userId", request.getUserId());
        response.getExtra().put("sessionId", request.getSessionId());

        // 记录响应日志
        log.debug("后处理AI聊天响应 - 用户: {}, 成功: {}",
                request.getUserId(), response.getSuccess());
    }

    /**
     * 创建错误响应
     *
     * @param error   错误信息
     * @param request 原始请求
     * @return 错误响应
     */
    private AiChatResponse createErrorResponse(Throwable error, AiChatRequest request) {
        return new AiChatResponse()
                .setSuccess(false)
                .setError(error.getMessage())
                .setErrorCode("CHAT_ERROR")
                .setModel(request.getModel())
                .setCreateTime(java.time.LocalDateTime.now());
    }

    /**
     * 流式回调接口
     */
    public interface StreamCallback {
        /**
         * 接收流式数据
         *
         * @param chunk 数据块
         */
        void onChunk(String chunk);

        /**
         * 流式完成
         *
         * @param response 完整响应
         */
        void onComplete(AiChatResponse response);

        /**
         * 流式错误
         *
         * @param error 错误信息
         */
        void onError(Throwable error);
    }
}
