package com.yushu.system.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yushu.common.utils.SecurityUtils;
import com.yushu.system.domain.AiConversation;
import com.yushu.system.domain.AiMessage;
import com.yushu.system.domain.AiService;
import com.yushu.system.mapper.AiConversationMapper;
import com.yushu.system.mapper.AiMessageMapper;
import com.yushu.system.service.IAiChatService;
import com.yushu.system.service.IAiServiceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * AI对话Service业务层处理（简化版，基于AiService）
 * 
 * @author yushu
 */
@Service
public class AiChatServiceImpl implements IAiChatService {
    
    private static final Logger logger = LoggerFactory.getLogger(AiChatServiceImpl.class);
    
    @Autowired
    private IAiServiceService aiServiceService;
    
    @Autowired
    private AiConversationMapper conversationMapper;
    
    @Autowired
    private AiMessageMapper messageMapper;
    
    private final ExecutorService executor = Executors.newCachedThreadPool();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Map<String, Object> sendMessage(Long serviceId, String message, Long conversationId, String thinkingType) throws Exception {
        // 获取AI服务配置（解密后的完整配置）
        AiService service = aiServiceService.selectFullServiceById(serviceId);
        if (service == null) {
            throw new Exception("AI服务不存在");
        }
        
        // 验证API密钥
        if (service.getApiKey() == null || service.getApiKey().trim().isEmpty()) {
            throw new Exception("API密钥未配置，请在服务配置中填写有效的API密钥");
        }

        // 如果没有会话ID，创建新会话
        if (conversationId == null) {
            AiConversation conversation = new AiConversation();
            conversation.setUserId(SecurityUtils.getUserId());
            conversation.setServiceId(serviceId);
            conversation.setTitle("新对话");
            conversation.setSystemPrompt(service.getSystemPrompt());
            conversation.setMessageCount(0);
            conversation.setTotalTokens(0);
            conversation.setStatus("0");
            conversation.setIsPinned("0");
            conversationMapper.insertAiConversation(conversation);
            conversationId = conversation.getConversationId();
        }

        // 保存用户消息
        AiMessage userMessage = new AiMessage();
        userMessage.setConversationId(conversationId);
        userMessage.setRole("user");
        userMessage.setContent(message);
        userMessage.setIsError("0");
        messageMapper.insertAiMessage(userMessage);

        // 调用AI接口
        long startTime = System.currentTimeMillis();
        String response = callAiApi(service, conversationId, message, thinkingType);
        long responseTime = System.currentTimeMillis() - startTime;

        // 保存AI响应
        AiMessage assistantMessage = new AiMessage();
        assistantMessage.setConversationId(conversationId);
        assistantMessage.setRole("assistant");
        assistantMessage.setContent(response);
        assistantMessage.setResponseTime((int) responseTime);
        assistantMessage.setIsError("0");
        messageMapper.insertAiMessage(assistantMessage);

        // 更新会话统计
        AiConversation conversation = conversationMapper.selectAiConversationByConversationId(conversationId);
        conversation.setMessageCount(conversation.getMessageCount() + 2);
        conversation.setLastMessageTime(new Date());
        conversationMapper.updateAiConversation(conversation);

        Map<String, Object> result = new HashMap<>();
        result.put("conversationId", conversationId);
        result.put("message", response);
        result.put("responseTime", responseTime);
        return result;
    }

    @Override
    public SseEmitter streamMessage(Long serviceId, String message, Long conversationId, String thinkingType, Boolean enableSearch, String images, String fileUrls) throws Exception {
        SseEmitter emitter = new SseEmitter(600000L); // 10分钟超时
        
        final Long finalConversationId = conversationId;
        final Long finalServiceId = serviceId;
        final Boolean finalEnableSearch = enableSearch;
        final String finalImages = images;
        final String finalFileUrls = fileUrls;
        // 在主线程中获取用户ID，避免异步线程中 SecurityContext 不可用
        final Long userId = SecurityUtils.getUserId();
        
        executor.execute(() -> {
            Long currentConversationId = finalConversationId;
            
            try {
                // 获取AI服务配置
                AiService service = aiServiceService.selectFullServiceById(finalServiceId);
                if (service == null) {
                    emitter.send(SseEmitter.event().name("error").data("AI服务不存在"));
                    emitter.complete();
                    return;
                }
                
                // 创建或获取会话
                if (currentConversationId == null) {
                    AiConversation conversation = new AiConversation();
                    conversation.setUserId(userId);
                    conversation.setServiceId(finalServiceId);
                    conversation.setTitle("新对话");
                    conversation.setSystemPrompt(service.getSystemPrompt());
                    conversation.setMessageCount(0);
                    conversation.setTotalTokens(0);
                    conversation.setStatus("0");
                    conversation.setIsPinned("0");
                    conversationMapper.insertAiConversation(conversation);
                    currentConversationId = conversation.getConversationId();
                    
                    // 发送会话ID
                    Map<String, Object> initData = new HashMap<>();
                    initData.put("conversationId", currentConversationId);
                    emitter.send(SseEmitter.event().data(initData));
                }
                
                // 处理文件URL，读取文件内容并附加到消息
                String enhancedMessage = message;
                if (finalFileUrls != null && !finalFileUrls.isEmpty()) {
                    try {
                        List<String> urls = objectMapper.readValue(finalFileUrls, List.class);
                        StringBuilder fileContents = new StringBuilder();
                        for (String url : urls) {
                            String content = readFileContent(url);
                            if (content != null && !content.isEmpty()) {
                                fileContents.append("\n\n--- 文件内容 ---\n").append(content).append("\n--- 文件结束 ---\n");
                            }
                        }
                        if (fileContents.length() > 0) {
                            enhancedMessage = message + fileContents.toString();
                        }
                    } catch (Exception e) {
                        // 文件读取失败，继续使用原始消息
                    }
                }
                
                final String finalMessage = enhancedMessage;
                
                // 保存用户消息
                AiMessage userMessage = new AiMessage();
                userMessage.setConversationId(currentConversationId);
                userMessage.setRole("user");
                userMessage.setContent(message); // 保存原始消息
                userMessage.setIsError("0");
                messageMapper.insertAiMessage(userMessage);
                
                // 流式调用AI API（使用增强后的消息）
                StringBuilder fullResponse = new StringBuilder();
                StringBuilder fullReasoning = new StringBuilder();
                callAiApiStream(service, currentConversationId, finalMessage, thinkingType, finalEnableSearch, finalImages, (chunk, reasoning) -> {
                    try {
                        Map<String, Object> data = new HashMap<>();
                        
                        // 发送增量内容
                        if (chunk != null && !chunk.isEmpty()) {
                            fullResponse.append(chunk);
                            data.put("content", chunk);
                        }
                        if (reasoning != null && !reasoning.isEmpty()) {
                            fullReasoning.append(reasoning);
                            data.put("reasoning", reasoning);
                        }
                        
                        if (!data.isEmpty()) {
                            emitter.send(SseEmitter.event().data(data));
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
                
                // 保存AI响应
                AiMessage assistantMessage = new AiMessage();
                assistantMessage.setConversationId(currentConversationId);
                assistantMessage.setRole("assistant");
                assistantMessage.setContent(fullResponse.toString());
                if (fullReasoning.length() > 0) {
                    assistantMessage.setReasoning(fullReasoning.toString());
                }
                assistantMessage.setIsError("0");
                messageMapper.insertAiMessage(assistantMessage);
                
                // 更新会话统计
                AiConversation conversation = conversationMapper.selectAiConversationByConversationId(currentConversationId);
                conversation.setMessageCount(conversation.getMessageCount() + 2);
                conversation.setLastMessageTime(new Date());
                conversationMapper.updateAiConversation(conversation);
                
                // 发送完成事件
                emitter.send(SseEmitter.event().name("done").data("completed"));
                emitter.complete();
                
            } catch (Exception e) {
                try {
                    emitter.send(SseEmitter.event().name("error").data("错误: " + e.getMessage()));
                } catch (Exception ignored) {}
                emitter.completeWithError(e);
            }
        });
        
        return emitter;
    }

    @Override
    public List<Map<String, Object>> getConversationHistory(Long conversationId) {
        List<AiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
        List<Map<String, Object>> history = new ArrayList<>();
        
        for (AiMessage msg : messages) {
            Map<String, Object> item = new HashMap<>();
            item.put("messageId", msg.getMessageId());
            item.put("role", msg.getRole());
            item.put("content", msg.getContent());
            item.put("reasoning", msg.getReasoning()); // 添加reasoning字段
            item.put("createTime", msg.getCreateTime());
            item.put("responseTime", msg.getResponseTime());
            history.add(item);
        }
        
        return history;
    }

    @Override
    public Map<String, Object> createConversation(Long serviceId, String title) {
        AiService service = aiServiceService.selectAiServiceByServiceId(serviceId);
        
        AiConversation conversation = new AiConversation();
        conversation.setUserId(SecurityUtils.getUserId());
        conversation.setServiceId(serviceId);
        conversation.setTitle(title != null ? title : "新对话");
        conversation.setSystemPrompt(service != null ? service.getSystemPrompt() : null);
        conversation.setMessageCount(0);
        conversation.setTotalTokens(0);
        conversation.setStatus("0");
        conversation.setIsPinned("0");
        conversationMapper.insertAiConversation(conversation);
        
        Map<String, Object> result = new HashMap<>();
        result.put("conversationId", conversation.getConversationId());
        result.put("title", conversation.getTitle());
        return result;
    }

    @Override
    public List<Map<String, Object>> getUserConversations() {
        AiConversation query = new AiConversation();
        query.setUserId(SecurityUtils.getUserId());
        query.setStatus("0"); // 仅查询正常会话
        
        List<AiConversation> conversations = conversationMapper.selectAiConversationList(query);
        List<Map<String, Object>> result = new ArrayList<>();
        
        for (AiConversation conv : conversations) {
            Map<String, Object> item = new HashMap<>();
            item.put("conversationId", conv.getConversationId());
            item.put("serviceId", conv.getServiceId());
            item.put("title", conv.getTitle());
            item.put("serviceName", conv.getServiceName());
            item.put("messageCount", conv.getMessageCount());
            item.put("lastMessageTime", conv.getLastMessageTime());
            item.put("createTime", conv.getCreateTime());
            result.add(item);
        }
        
        return result;
    }

    @Override
    public int deleteConversation(Long conversationId) {
        // 软删除：更新状态为已删除
        AiConversation conversation = new AiConversation();
        conversation.setConversationId(conversationId);
        conversation.setStatus("2"); // 2=已删除
        return conversationMapper.updateAiConversation(conversation);
    }

    /**
     * 读取文件内容
     */
    private String readFileContent(String fileUrl) {
        try {
            // 将URL转换为本地文件路径
            String localPath = null;
            if (fileUrl.contains("/profile/upload/")) {
                // 从配置中获取上传路径前缀
                String profilePath = System.getProperty("user.dir") + "/uploadPath";
                // 尝试从 application.yml 读取
                try {
                    profilePath = com.yushu.common.config.YuShuConfig.getProfile();
                } catch (Exception e) {
                    // 使用默认路径
                }
                String relativePath = fileUrl.substring(fileUrl.indexOf("/profile/upload/") + "/profile/upload/".length());
                localPath = profilePath + "/" + relativePath;
            } else if (fileUrl.startsWith("http")) {
                // 远程URL，暂不支持
                return null;
            } else {
                localPath = fileUrl;
            }
            
            if (localPath != null) {
                java.io.File file = new java.io.File(localPath);
                if (file.exists() && file.isFile()) {
                    // 检查文件大小，避免读取过大的文件
                    if (file.length() > 1024 * 1024) { // 1MB 限制
                        return "[文件过大，无法读取]";
                    }
                    // 读取文件内容
                    return new String(java.nio.file.Files.readAllBytes(file.toPath()), java.nio.charset.StandardCharsets.UTF_8);
                }
            }
        } catch (Exception e) {
            // 读取失败
        }
        return null;
    }
    
    /**
     * 流式回调接口
     */
    @FunctionalInterface
    private interface StreamCallback {
        void onChunk(String chunk, String reasoning);
    }

    /**
     * 调用AI API（流式）
     */
    private void callAiApiStream(AiService service, Long conversationId, String message, String thinkingType, Boolean enableSearch, String imagesJson, StreamCallback callback) throws Exception {
        // 获取历史消息
        List<AiMessage> history = messageMapper.selectMessagesByConversationId(conversationId);
        
        // 构建消息列表
        List<Map<String, Object>> messages = new ArrayList<>();
        
        // 添加系统提示词
        if (service.getSystemPrompt() != null && !service.getSystemPrompt().isEmpty()) {
            Map<String, Object> systemMsg = new HashMap<>();
            systemMsg.put("role", "system");
            systemMsg.put("content", service.getSystemPrompt());
            messages.add(systemMsg);
        }
        
        // 添加历史消息（限制数量）
        int historyLimit = 10;
        int startIndex = Math.max(0, history.size() - historyLimit);
        for (int i = startIndex; i < history.size(); i++) {
            AiMessage msg = history.get(i);
            Map<String, Object> historyMsg = new HashMap<>();
            historyMsg.put("role", msg.getRole());
            historyMsg.put("content", msg.getContent());
            messages.add(historyMsg);
        }
        
        // 添加当前消息（支持多模态）
        Map<String, Object> userMsg = new HashMap<>();
        userMsg.put("role", "user");
        
        // 检查是否有图片（多模态消息）
        boolean hasValidImages = false;
        List<String> imageDataList = null;
        
        if (imagesJson != null && !imagesJson.isEmpty() && "1".equals(service.getSupportsVision())) {
            try {
                imageDataList = objectMapper.readValue(imagesJson, List.class);
                // 过滤掉空字符串
                if (imageDataList != null) {
                    imageDataList = imageDataList.stream()
                        .filter(img -> img != null && !img.isEmpty())
                        .collect(java.util.stream.Collectors.toList());
                    hasValidImages = !imageDataList.isEmpty();
                }
            } catch (Exception e) {
                hasValidImages = false;
            }
        }
        
        if (hasValidImages && imageDataList != null) {
            // 构建多模态内容
            List<Map<String, Object>> contentList = new ArrayList<>();
            
            // 添加文本内容
            Map<String, Object> textContent = new HashMap<>();
            textContent.put("type", "text");
            textContent.put("text", message);
            contentList.add(textContent);
            
            // 添加图片内容
            for (String imageData : imageDataList) {
                Map<String, Object> imageContent = new HashMap<>();
                imageContent.put("type", "image_url");
                Map<String, String> imageUrl = new HashMap<>();
                imageUrl.put("url", imageData); // base64 data URL
                imageContent.put("image_url", imageUrl);
                contentList.add(imageContent);
            }
            
            userMsg.put("content", contentList);
        } else {
            // 普通文本消息
            userMsg.put("content", message);
        }
        messages.add(userMsg);
        
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", service.getModelCode());
        requestBody.put("messages", messages);
        
        // 使用安全的参数值
        if (service.getTemperature() != null) {
            double temperature = service.getTemperature().doubleValue();
            if (temperature >= 0 && temperature <= 2) {
                requestBody.put("temperature", temperature);
            }
        }
        
        Integer maxTokens = service.getMaxTokens();
        if (maxTokens != null && maxTokens > 0) {
            requestBody.put("max_tokens", maxTokens);
        }
        
        requestBody.put("stream", true);
        
        // 添加深度思考参数（仅在启用时发送）
        if ("1".equals(service.getSupportsThinking()) && "enabled".equals(thinkingType)) {
            Map<String, String> thinking = new HashMap<>();
            thinking.put("type", "enabled");
            requestBody.put("thinking", thinking);
        }
        
        // 添加联网搜索参数
        if ("1".equals(service.getSupportsSearch()) && Boolean.TRUE.equals(enableSearch)) {
            requestBody.put("web_search", true);
        }
        
        // 发送HTTP请求
        URL url = new URL(service.getApiUrl());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setRequestProperty("Authorization", "Bearer " + service.getApiKey());
        conn.setDoOutput(true);
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(300000);
        
        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = objectMapper.writeValueAsString(requestBody).getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        
        int responseCode = conn.getResponseCode();
        if (responseCode != 200) {
            // 读取错误响应体
            String errorBody = "";
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) {
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                errorBody = sb.toString();
            } catch (Exception e) {
                errorBody = "无法读取错误信息";
            }
            throw new Exception("API调用失败，状态码: " + responseCode + ", 错误信息: " + errorBody);
        }
        
        // 逐行读取SSE流
        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (line.startsWith("data: ")) {
                    String data = line.substring(6).trim();
                    if ("[DONE]".equals(data)) break;
                    if (data.isEmpty()) continue;
                    
                    try {
                        @SuppressWarnings("unchecked")
                        Map<String, Object> chunk = objectMapper.readValue(data, Map.class);
                        @SuppressWarnings("unchecked")
                        List<Map<String, Object>> choices = (List<Map<String, Object>>) chunk.get("choices");
                        
                        if (choices != null && !choices.isEmpty()) {
                            @SuppressWarnings("unchecked")
                            Map<String, Object> delta = (Map<String, Object>) choices.get(0).get("delta");
                            if (delta != null) {
                                String reasoning = (String) delta.get("reasoning_content");
                                String content = (String) delta.get("content");
                                if (reasoning != null || content != null) {
                                    callback.onChunk(content, reasoning);
                                }
                            }
                        }
                    } catch (Exception e) {
                        logger.warn("解析SSE数据失败: {}", e.getMessage());
                    }
                }
            }
        }
    }

    /**
     * 调用AI API（非流式）
     */
    private String callAiApi(AiService service, Long conversationId, String message, String thinkingType) throws Exception {
        // 获取历史消息
        List<AiMessage> history = messageMapper.selectMessagesByConversationId(conversationId);
        
        // 构建消息列表
        List<Map<String, String>> messages = new ArrayList<>();
        
        // 添加系统提示词
        if (service.getSystemPrompt() != null && !service.getSystemPrompt().isEmpty()) {
            Map<String, String> systemMsg = new HashMap<>();
            systemMsg.put("role", "system");
            systemMsg.put("content", service.getSystemPrompt());
            messages.add(systemMsg);
        }
        
        // 添加历史消息
        int historyLimit = 10;
        int startIndex = Math.max(0, history.size() - historyLimit);
        for (int i = startIndex; i < history.size(); i++) {
            AiMessage msg = history.get(i);
            Map<String, String> historyMsg = new HashMap<>();
            historyMsg.put("role", msg.getRole());
            historyMsg.put("content", msg.getContent());
            messages.add(historyMsg);
        }
        
        // 添加当前消息
        Map<String, String> userMsg = new HashMap<>();
        userMsg.put("role", "user");
        userMsg.put("content", message);
        messages.add(userMsg);
        
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", service.getModelCode());
        requestBody.put("messages", messages);
        requestBody.put("temperature", service.getTemperature());
        requestBody.put("max_tokens", service.getMaxTokens());
        requestBody.put("stream", false);
        
        // 添加深度思考参数
        if ("1".equals(service.getSupportsThinking()) && "enabled".equals(thinkingType)) {
            Map<String, String> thinking = new HashMap<>();
            thinking.put("type", "enabled");
            requestBody.put("thinking", thinking);
        }
        
        // 发送HTTP请求
        URL url = new URL(service.getApiUrl());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setRequestProperty("Authorization", "Bearer " + service.getApiKey());
        conn.setDoOutput(true);
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(60000);
        
        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = objectMapper.writeValueAsString(requestBody).getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        
        int responseCode = conn.getResponseCode();
        if (responseCode != 200) {
            throw new Exception("API调用失败，状态码: " + responseCode);
        }
        
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = br.readLine()) != null) {
                response.append(line);
            }
        }
        
        @SuppressWarnings("unchecked")
        Map<String, Object> responseData = objectMapper.readValue(response.toString(), Map.class);
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> choices = (List<Map<String, Object>>) responseData.get("choices");
        if (choices == null || choices.isEmpty()) {
            throw new Exception("API响应格式错误");
        }
        
        @SuppressWarnings("unchecked")
        Map<String, Object> messageObj = (Map<String, Object>) choices.get(0).get("message");
        return (String) messageObj.get("content");
    }
}

