package org.xyzh.ai.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.xyzh.ai.client.DifyApiClient;
import org.xyzh.ai.client.callback.StreamCallback;
import org.xyzh.ai.client.dto.ChatRequest;
import org.xyzh.ai.client.dto.ChatResponse;
import org.xyzh.ai.exception.DifyException;
import org.xyzh.ai.mapper.AiAgentConfigMapper;
import org.xyzh.ai.mapper.AiConversationMapper;
import org.xyzh.ai.mapper.AiMessageMapper;
import org.xyzh.ai.mapper.AiUploadFileMapper;
import org.xyzh.ai.service.AiKnowledgeRedisService;
import org.xyzh.api.ai.chat.AiChatService;
import org.xyzh.api.ai.dto.DifyFileInfo;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.ai.TbAiAgentConfig;
import org.xyzh.common.dto.ai.TbAiConversation;
import org.xyzh.common.dto.ai.TbAiMessage;
import org.xyzh.common.dto.ai.TbAiUploadFile;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.vo.UserDeptRoleVO;
import org.xyzh.system.utils.LoginUtil;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @description AI对话服务实现
 * @filename AiChatServiceImpl.java
 * @author AI Assistant
 * @copyright xyzh
 * @since 2025-11-04
 */
@Slf4j
@Service
public class AiChatServiceImpl implements AiChatService {

    @Autowired
    private AiConversationMapper conversationMapper;

    @Autowired
    private AiMessageMapper messageMapper;

    @Autowired
    private AiAgentConfigMapper agentConfigMapper;

    @Autowired
    private DifyApiClient difyApiClient;

    @Autowired
    private AiKnowledgeRedisService knowledgeRedisService;

    @Autowired
    private AiUploadFileMapper uploadFileMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 异步任务线程池（用于异步生成摘要等后台任务）
    private final ExecutorService executorService = Executors.newFixedThreadPool(3);
    
    // Redis会话key前缀
    private static final String CHAT_SESSION_PREFIX = "chat:session:";

    @Override
    public ResultDomain<String> prepareChatSession(String agentId, String conversationId, String query, List<DifyFileInfo> filesData) {
        ResultDomain<String> resultDomain = new ResultDomain<>();
        try {
            // 参数验证
            if (!StringUtils.hasText(agentId)) {
                resultDomain.fail("智能体ID不能为空");
                return resultDomain;
            }
            if (!StringUtils.hasText(query)) {
                resultDomain.fail("问题不能为空");
                return resultDomain;
            }

            // 生成sessionId
            String sessionId = UUID.randomUUID().toString();
            
            // 构建会话数据
            Map<String, Object> sessionData = new HashMap<>();
            sessionData.put("agentId", agentId);
            sessionData.put("conversationId", conversationId);
            sessionData.put("query", query);
            sessionData.put("filesData", filesData);
            sessionData.put("createTime", System.currentTimeMillis());
            
            // 存入Redis，5分钟过期
            String redisKey = CHAT_SESSION_PREFIX + sessionId;
            redisTemplate.opsForValue().set(redisKey, sessionData, 5, TimeUnit.MINUTES);
            
            log.info("创建对话会话: sessionId={}, agentId={}", sessionId, agentId);
            
            resultDomain.success("会话创建成功", sessionId);
            return resultDomain;
        } catch (Exception e) {
            log.error("创建对话会话失败", e);
            resultDomain.fail("创建会话失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public SseEmitter streamChatWithSse(String sessionId) {
        // 创建SseEmitter，设置超时时间为5分钟
        SseEmitter emitter = new SseEmitter(5 * 60 * 1000L);
        
        try {
            // 1. 从Redis获取并删除会话数据
            String redisKey = CHAT_SESSION_PREFIX + sessionId;
            Map<String, Object> sessionData = (Map<String, Object>) redisTemplate.opsForValue().get(redisKey);
            
            if (sessionData == null) {
                emitter.send(SseEmitter.event().name("error").data("会话不存在或已过期"));
                emitter.complete();
                return emitter;
            }
            
            // 删除Redis中的会话数据（一次性使用）
            redisTemplate.delete(redisKey);

            String agentId = (String) sessionData.get("agentId");
            String conversationId = (String) sessionData.get("conversationId");
            String query = (String) sessionData.get("query");
            
            // 转换文件数据
            List<DifyFileInfo> filesData = null;
            Object filesObj = sessionData.get("filesData");
            if (filesObj != null) {
                if (filesObj instanceof List) {
                    filesData = new ArrayList<>();
                    for (Object fileObj : (List<?>) filesObj) {
                        if (fileObj instanceof Map) {
                            // 使用Fastjson2转换Map为对象
                            String json = JSON.toJSONString(fileObj);
                            DifyFileInfo fileInfo = JSON.parseObject(json, DifyFileInfo.class);
                            filesData.add(fileInfo);
                        } else if (fileObj instanceof DifyFileInfo) {
                            filesData.add((DifyFileInfo) fileObj);
                        }
                    }
                }
            }

            // 2. 参数验证
            if (!StringUtils.hasText(agentId)) {
                emitter.send(SseEmitter.event().name("error").data("智能体ID不能为空"));
                emitter.complete();
                return emitter;
            }
            if (!StringUtils.hasText(query)) {
                emitter.send(SseEmitter.event().name("error").data("问题不能为空"));
                emitter.complete();
                return emitter;
            }

            // 2. 获取当前用户（在主线程中，可以正常获取）
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                emitter.send(SseEmitter.event().name("error").data("用户未登录"));
                emitter.complete();
                return emitter;
            }

            // 3. 查询智能体配置
            TbAiAgentConfig agent = agentConfigMapper.selectAgentConfigById(agentId);
            if (agent == null || agent.getDeleted()) {
                emitter.send(SseEmitter.event().name("error").data("智能体不存在"));
                emitter.complete();
                return emitter;
            }
            if (agent.getStatus() != 1) {
                emitter.send(SseEmitter.event().name("error").data("智能体未启用"));
                emitter.complete();
                return emitter;
            }

            // 4. 获取或创建会话
            TbAiConversation conversation;
            if (StringUtils.hasText(conversationId)) {
                conversation = conversationMapper.selectConversationById(conversationId);
                if (conversation == null || conversation.getDeleted()) {
                    emitter.send(SseEmitter.event().name("error").data("会话不存在"));
                    emitter.complete();
                    return emitter;
                }
                if (!conversation.getUserID().equals(currentUser.getID())) {
                    emitter.send(SseEmitter.event().name("error").data("无权访问此会话"));
                    emitter.complete();
                    return emitter;
                }
            } else {
                // 创建新会话
                ResultDomain<TbAiConversation> createResult = createConversation(agentId, query.substring(0, 20));
                if (!createResult.isSuccess()) {
                    emitter.send(SseEmitter.event().name("error").data(createResult.getMessage()));
                    emitter.complete();
                    return emitter;
                }
                conversation = createResult.getData();
            }
            
            final String finalConversationId = conversation.getID();

            // 5. 创建用户消息记录
            TbAiMessage userMessage = new TbAiMessage();
            String userMessageId = UUID.randomUUID().toString();
            userMessage.setID(userMessageId);
            userMessage.setConversationID(finalConversationId);
            userMessage.setAgentID(agentId);
            userMessage.setRole("user");
            userMessage.setContent(query);
            userMessage.setCreateTime(new Date());
            userMessage.setUpdateTime(new Date());
            userMessage.setDeleted(false);
            userMessage.setUserID(currentUser.getID());
            
            // 处理文件关联（将文件ID列表转换为JSON数组保存）
            if (filesData != null && !filesData.isEmpty()) {
                try {
                    // 提取系统文件ID列表（从前端传来的sysFileId）
                    List<String> sysFileIds = new ArrayList<>();
                    for (DifyFileInfo fileInfo : filesData) {
                        // 使用sysFileId字段
                        if (fileInfo.getSysFileId() != null) {
                            sysFileIds.add(fileInfo.getSysFileId());
                        }
                    }
                    if (!sysFileIds.isEmpty()) {
                        // 使用Fastjson2序列化为JSON字符串
                        userMessage.setFileIDs(JSON.toJSONString(sysFileIds));
                    }
                } catch (Exception e) {
                    log.warn("保存文件ID列表失败", e);
                }
            }
            
            messageMapper.insertMessage(userMessage);
            
            // 6. 保存文件关联记录到tb_ai_upload_file
            if (filesData != null && !filesData.isEmpty()) {
                saveMessageFileRecords(userMessageId, finalConversationId, currentUser.getID(), filesData);
            }

            // 注意：AI消息记录将在获取到Dify的task_id后创建

            // 6. 从Redis获取当前用户可访问的知识库ID列表
            List<String> knowledgeIds = getKnowledgeIdsByUser(currentUser);

            // 7. 构建Dify请求
            ChatRequest chatRequest = new ChatRequest();
            chatRequest.setQuery(query);
            chatRequest.setUser(currentUser.getID());
            
            if (StringUtils.hasText(conversation.getDifyConversationId())) {
                chatRequest.setConversationId(conversation.getDifyConversationId());
            }

            chatRequest.setResponseMode("streaming");
            Map<String, Object> inputs = new HashMap<>();
            inputs.put("connectInternet", agent.getConnectInternet());
            inputs.put("datasets", JSON.toJSONString(knowledgeIds));
            chatRequest.setInputs(inputs);
            chatRequest.setFiles(filesData);
            // 6. 调用Dify流式对话
            final TbAiConversation finalConversation = conversation;
            StringBuilder fullAnswer = new StringBuilder();
            AtomicReference<String> difyConversationId = new AtomicReference<>();
            AtomicReference<String> difyMessageId = new AtomicReference<>();
            AtomicReference<String> taskId = new AtomicReference<>(); // 用于存储Dify的task_id
            AtomicReference<Boolean> messageCreated = new AtomicReference<>(false); // 标记消息是否已创建
            AtomicReference<Boolean> isStopped = new AtomicReference<>(false); // 标记是否已停止
            difyApiClient.streamChat(chatRequest, agent.getDifyApiKey(), new StreamCallback() {
                @Override
                public void onMessage(String message) {
                    if (isStopped.get()) {
                        return; // 已停止，不再处理
                    }
                    try {
                        fullAnswer.append(message);
                        // 发送消息片段给前端
                        emitter.send(SseEmitter.event().name("message").data(message));
                    } catch (IllegalStateException e) {
                        // SseEmitter已关闭（用户停止生成），标记为已停止
                        isStopped.set(true);
                        log.debug("SSE连接已关闭，停止发送消息");
                    } catch (IOException e) {
                        log.error("发送SSE消息失败", e);
                    }
                }

                @Override
                public void onMessageEnd(String metadata) {
                    if (isStopped.get()) {
                        return; // 已停止，不再处理
                    }
                    try {
                        // 使用Fastjson2解析metadata
                        JSONObject json = JSON.parseObject(metadata);
                        if (json.containsKey("conversation_id")) {
                            difyConversationId.set(json.getString("conversation_id"));
                        }
                        if (json.containsKey("id")) {
                            difyMessageId.set(json.getString("id"));
                        }

                        // 更新AI消息内容（使用task_id作为消息ID）
                        if (taskId.get() != null) {
                            TbAiMessage updateMessage = new TbAiMessage();
                            updateMessage.setID(taskId.get());
                            updateMessage.setContent(fullAnswer.toString());
                            updateMessage.setDifyMessageId(difyMessageId.get());
                            updateMessage.setUpdateTime(new Date());
                            messageMapper.updateMessage(updateMessage);
                        }

                        // 更新会话的Dify会话ID
                        if (StringUtils.hasText(difyConversationId.get())) {
                            TbAiConversation updateConv = new TbAiConversation();
                            updateConv.setID(finalConversationId);
                            updateConv.setDifyConversationId(difyConversationId.get());
                            updateConv.setMessageCount((finalConversation.getMessageCount() != null ? 
                                    finalConversation.getMessageCount() : 0) + 2);
                            updateConv.setUpdateTime(new Date());
                            conversationMapper.updateConversation(updateConv);
                        }

                        // 发送结束事件（保持兼容）
                        emitter.send(SseEmitter.event().name("end").data(metadata));
                    } catch (IllegalStateException e) {
                        // SseEmitter已关闭，标记为已停止
                        isStopped.set(true);
                        log.debug("SSE连接已关闭，停止处理");
                    } catch (Exception e) {
                        log.error("处理流式响应metadata失败", e);
                    }
                }
                
                @Override
                public void onEvent(String eventType, String eventData) {
                    if (isStopped.get()) {
                        return; // 已停止，不再处理
                    }
                    try {
                        // 转发所有Dify原始事件到前端（包含task_id等完整信息）
                        emitter.send(SseEmitter.event().name("dify_" + eventType).data(eventData));
                        log.debug("转发Dify事件: {} - {}", eventType, eventData);
                        
                        // 如果还没有创建消息记录，尝试从任何事件中提取task_id
                        if (!messageCreated.get()) {
                            JSONObject json = JSON.parseObject(eventData);
                            if (json.containsKey("task_id")) {
                                String difyTaskId = json.getString("task_id");
                                
                                // 只有在taskId为空时才设置并创建消息
                                if (taskId.get() == null) {
                                    taskId.set(difyTaskId);
                                    
                                    // 使用task_id作为消息ID，创建AI消息记录
                                    TbAiMessage aiMessage = new TbAiMessage();
                                    aiMessage.setID(difyTaskId);  // 使用Dify的task_id作为消息ID
                                    aiMessage.setConversationID(finalConversationId);
                                    aiMessage.setAgentID(agentId);
                                    aiMessage.setRole("assistant");
                                    aiMessage.setContent("");
                                    aiMessage.setCreateTime(new Date());
                                    aiMessage.setUpdateTime(new Date());
                                    aiMessage.setDeleted(false);
                                    aiMessage.setUserID("assistant");
                                    messageMapper.insertMessage(aiMessage);
                                    
                                    messageCreated.set(true);
                                    log.info("AI消息记录已创建（从{}事件提取task_id）: {}", eventType, difyTaskId);
                                    
                                    // 发送init事件给前端，包含task_id（作为messageId）
                                    Map<String, String> initData = new HashMap<>();
                                    initData.put("conversationId", finalConversationId);
                                    initData.put("messageId", difyTaskId);
                                    emitter.send(SseEmitter.event().name("init").data(initData));
                                }
                            }
                        }
                    } catch (IllegalStateException e) {
                        // SseEmitter已关闭，标记为已停止
                        isStopped.set(true);
                        log.debug("SSE连接已关闭，停止转发事件");
                    } catch (IOException e) {
                        log.error("转发Dify事件失败: {}", eventType, e);
                    } catch (Exception e) {
                        log.error("处理Dify事件异常: {}", eventType, e);
                    }
                }

                @Override
                public void onComplete() {
                    if (isStopped.get()) {
                        log.debug("SSE连接已关闭，跳过完成处理");
                        return; // 已停止，不再处理
                    }
                    try {
                        log.info("流式对话完成: {} - {}", finalConversationId, taskId.get());
                        emitter.send(SseEmitter.event().name("complete").data("对话完成"));
                        emitter.complete();
                    } catch (IllegalStateException e) {
                        // SseEmitter已关闭
                        isStopped.set(true);
                        log.debug("SSE连接已关闭");
                    } catch (IOException e) {
                        log.error("发送完成事件失败", e);
                        emitter.completeWithError(e);
                    }
                }

                @Override
                public void onError(Throwable error) {
                    if (isStopped.get()) {
                        log.debug("SSE连接已关闭，跳过错误处理");
                        return; // 已停止，不再处理
                    }
                    try {
                        log.error("流式对话失败", error);
                        emitter.send(SseEmitter.event().name("error").data(error.getMessage()));
                        emitter.completeWithError(error);
                    } catch (IllegalStateException e) {
                        // SseEmitter已关闭
                        isStopped.set(true);
                        log.debug("SSE连接已关闭");
                    } catch (IOException e) {
                        log.error("发送错误事件失败", e);
                        emitter.completeWithError(e);
                    }
                }
            });

            // 设置超时和错误回调
            emitter.onTimeout(() -> {
                isStopped.set(true);
                log.warn("SSE连接超时");
                emitter.complete();
            });
            
            emitter.onError(e -> {
                isStopped.set(true);
                log.error("SSE连接错误（可能是用户停止生成）", e);
                emitter.completeWithError(e);
            });

        } catch (Exception e) {
            log.error("流式对话异常", e);
            try {
                emitter.send(SseEmitter.event().name("error").data(e.getMessage()));
                emitter.completeWithError(e);
            } catch (IOException ex) {
                log.error("发送异常事件失败", ex);
                emitter.completeWithError(ex);
            }
        }

        return emitter;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAiMessage> blockingChat(
            String agentId,
            String conversationId,
            String query){
        ResultDomain<TbAiMessage> resultDomain = new ResultDomain<>();

        try {
            // 参数验证（同streamChat）
            if (!StringUtils.hasText(agentId) || !StringUtils.hasText(query)) {
                resultDomain.fail("参数不能为空");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            // 查询智能体
            TbAiAgentConfig agent = agentConfigMapper.selectAgentConfigById(agentId);
            if (agent == null || agent.getStatus() != 1) {
                resultDomain.fail("智能体不可用");
                return resultDomain;
            }

            // 获取或创建会话（同streamChat）
            TbAiConversation conversation;
            if (StringUtils.hasText(conversationId)) {
                conversation = conversationMapper.selectConversationById(conversationId);
                if (conversation == null || !conversation.getUserID().equals(currentUser.getID())) {
                    resultDomain.fail("会话不存在或无权访问");
                    return resultDomain;
                }
            } else {
                ResultDomain<TbAiConversation> createResult = createConversation(agentId, null);
                if (!createResult.isSuccess()) {
                    resultDomain.fail(createResult.getMessage());
                    return resultDomain;
                }
                conversation = createResult.getData();
                conversationId = conversation.getID();
            }

            // 创建用户消息
            TbAiMessage userMessage = new TbAiMessage();
            userMessage.setID(UUID.randomUUID().toString());
            userMessage.setConversationID(conversationId);
            userMessage.setAgentID(agentId);
            userMessage.setRole("user");
            userMessage.setContent(query);
            userMessage.setCreateTime(new Date());
            userMessage.setUpdateTime(new Date());
            userMessage.setDeleted(false);
            messageMapper.insertMessage(userMessage);

            // 构建Dify请求
            ChatRequest chatRequest = new ChatRequest();
            chatRequest.setQuery(query);
            chatRequest.setUser(currentUser.getID());
            
            if (StringUtils.hasText(conversation.getDifyConversationId())) {
                chatRequest.setConversationId(conversation.getDifyConversationId());
            }

            chatRequest.setResponseMode("blocking");
            Map<String, Object> inputs = new HashMap<>();
            inputs.put("connectInternet", agent.getConnectInternet());
            chatRequest.setInputs(inputs);
            chatRequest.setFiles(null);

            // 调用Dify阻塞式对话
            ChatResponse chatResponse = difyApiClient.blockingChat(chatRequest, agent.getDifyApiKey());

            // 创建AI回复消息
            TbAiMessage aiMessage = new TbAiMessage();
            aiMessage.setID(UUID.randomUUID().toString());
            aiMessage.setConversationID(conversationId);
            aiMessage.setAgentID(agentId);
            aiMessage.setRole("assistant");
            aiMessage.setContent(chatResponse.getAnswer());
            aiMessage.setDifyMessageId(chatResponse.getMessageId());
            aiMessage.setCreateTime(new Date());
            aiMessage.setUpdateTime(new Date());
            aiMessage.setDeleted(false);
            messageMapper.insertMessage(aiMessage);

            // 更新会话
            TbAiConversation updateConv = new TbAiConversation();
            updateConv.setID(conversationId);
            updateConv.setDifyConversationId(chatResponse.getConversationId());
            updateConv.setMessageCount((conversation.getMessageCount() != null ? 
                    conversation.getMessageCount() : 0) + 2);
            updateConv.setUpdateTime(new Date());
            conversationMapper.updateConversation(updateConv);

            log.info("阻塞式对话成功: {} - {}", conversationId, aiMessage.getID());
            resultDomain.success("对话成功", aiMessage);
            return resultDomain;

        } catch (DifyException e) {
            log.error("Dify阻塞式对话失败", e);
            resultDomain.fail("对话失败: " + e.getMessage());
            return resultDomain;
        } catch (Exception e) {
            log.error("阻塞式对话异常", e);
            resultDomain.fail("对话异常: " + e.getMessage());
            return resultDomain;
        }
    }
    
    @Override
    public ResultDomain<Boolean> stopChatByTaskId(String taskId, String agentId) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(taskId)) {
                resultDomain.fail("任务ID不能为空");
                return resultDomain;
            }
            
            if (!StringUtils.hasText(agentId)) {
                resultDomain.fail("智能体ID不能为空");
                return resultDomain;
            }

            // 获取智能体API Key
            TbAiAgentConfig agent = agentConfigMapper.selectAgentConfigById(agentId);
            if (agent == null) {
                resultDomain.fail("智能体不存在");
                return resultDomain;
            }

            // 调用Dify停止API
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null) {
                try {
                    difyApiClient.stopChatMessage(
                            taskId,
                            currentUser.getID(),
                            agent.getDifyApiKey()
                    );
                    log.info("对话停止成功，task_id: {}", taskId);
                    resultDomain.success("停止成功", true);
                } catch (DifyException e) {
                    log.error("停止对话失败", e);
                    resultDomain.fail("停止失败: " + e.getMessage());
                }
            } else {
                resultDomain.fail("用户未登录");
            }

            return resultDomain;

        } catch (Exception e) {
            log.error("停止对话异常", e);
            resultDomain.fail("停止异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAiConversation> createConversation(String agentId, String title) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(agentId)) {
                resultDomain.fail("智能体ID不能为空");
                return resultDomain;
            }

            // 获取当前用户
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            // 查询智能体
            TbAiAgentConfig agent = agentConfigMapper.selectAgentConfigById(agentId);
            if (agent == null || agent.getDeleted()) {
                resultDomain.fail("智能体不存在");
                return resultDomain;
            }

            // 创建会话
            TbAiConversation conversation = new TbAiConversation();
            conversation.setID(UUID.randomUUID().toString());
            conversation.setUserID(currentUser.getID());
            conversation.setAgentID(agentId);
            conversation.setTitle(StringUtils.hasText(title) ? title : "新对话");
            conversation.setMessageCount(0);
            conversation.setCreateTime(new Date());
            conversation.setUpdateTime(new Date());
            conversation.setDeleted(false);

            conversationMapper.insertConversation(conversation);

            log.info("创建会话成功: {} - {}", conversation.getID(), currentUser.getID());
            resultDomain.success("创建会话成功", conversation);
            return resultDomain;

        } catch (Exception e) {
            log.error("创建会话异常", e);
            resultDomain.fail("创建会话异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiConversation> getConversation(String conversationId) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            // 验证所属权
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权访问此会话");
                return resultDomain;
            }

            resultDomain.success("查询成功", conversation);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询会话异常", e);
            resultDomain.fail("查询异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<TbAiConversation> updateConversation(TbAiConversation conversation) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversation.getID())) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation existing = conversationMapper.selectConversationById(conversation.getID());
            if (existing == null || existing.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !existing.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权修改此会话");
                return resultDomain;
            }

            // 更新
            conversation.setUpdateTime(new Date());
            conversationMapper.updateConversation(conversation);

            // 重新查询
            TbAiConversation updated = conversationMapper.selectConversationById(conversation.getID());
            resultDomain.success("更新成功", updated);
            return resultDomain;

        } catch (Exception e) {
            log.error("更新会话异常", e);
            resultDomain.fail("更新异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> deleteConversation(String conversationId) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation existing = conversationMapper.selectConversationById(conversationId);
            if (existing == null || existing.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !existing.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权删除此会话");
                return resultDomain;
            }

            // 逻辑删除会话
            TbAiConversation deleteEntity = new TbAiConversation();
            deleteEntity.setID(conversationId);
            conversationMapper.deleteConversation(deleteEntity);

            // 同时逻辑删除该会话的所有消息
            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
            for (TbAiMessage message : messages) {
                TbAiMessage deleteMsg = new TbAiMessage();
                deleteMsg.setID(message.getID());
                messageMapper.deleteMessage(deleteMsg);
            }

            log.info("删除会话成功: {}", conversationId);
            resultDomain.success("删除成功", true);
            return resultDomain;

        } catch (Exception e) {
            log.error("删除会话异常", e);
            resultDomain.fail("删除异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiConversation> listUserConversations(String agentId) {
        ResultDomain<TbAiConversation> resultDomain = new ResultDomain<>();

        try {
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            List<TbAiConversation> conversations = conversationMapper.selectConversationsByUserId(
                    currentUser.getID(), agentId
            );

            resultDomain.success("查询成功", conversations);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询用户会话列表异常", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiMessage> listMessages(String conversationId) {
        ResultDomain<TbAiMessage> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(conversationId)) {
                resultDomain.fail("会话ID不能为空");
                return resultDomain;
            }

            // 验证所属权
            TbAiConversation conversation = conversationMapper.selectConversationById(conversationId);
            if (conversation == null || conversation.getDeleted()) {
                resultDomain.fail("会话不存在");
                return resultDomain;
            }

            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser != null && !conversation.getUserID().equals(currentUser.getID())) {
                resultDomain.fail("无权访问此会话");
                return resultDomain;
            }

            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
            resultDomain.success("查询成功", messages);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询消息列表异常", e);
            resultDomain.fail("查询失败: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbAiMessage> getMessage(String messageId) {
        ResultDomain<TbAiMessage> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(messageId)) {
                resultDomain.fail("消息ID不能为空");
                return resultDomain;
            }

            TbAiMessage message = messageMapper.selectMessageById(messageId);
            if (message == null || message.getDeleted()) {
                resultDomain.fail("消息不存在");
                return resultDomain;
            }

            resultDomain.success("查询成功", message);
            return resultDomain;

        } catch (Exception e) {
            log.error("查询消息异常", e);
            resultDomain.fail("查询异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    public SseEmitter regenerateAnswerWithSse(String messageId) {
        // 创建SseEmitter，设置超时时间为5分钟
        SseEmitter emitter = new SseEmitter(5 * 60 * 1000L);

        try {
            // 查询原消息
            TbAiMessage originalMessage = messageMapper.selectMessageById(messageId);
            if (originalMessage == null || originalMessage.getDeleted()) {
                emitter.send(SseEmitter.event().name("error").data("消息不存在"));
                emitter.complete();
                return emitter;
            }

            // 找到用户的原始问题（上一条消息）
            List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(
                    originalMessage.getConversationID()
            );
            
            TbAiMessage userQuestion = null;
            for (int i = messages.size() - 1; i >= 0; i--) {
                if ("user".equals(messages.get(i).getRole()) && 
                    !messages.get(i).getCreateTime().after(originalMessage.getCreateTime())) {
                    userQuestion = messages.get(i);
                    break;
                }
            }

            if (userQuestion == null) {
                emitter.send(SseEmitter.event().name("error").data("找不到原始问题"));
                emitter.complete();
                return emitter;
            }

            // 重新生成：创建临时session并调用新的streamChatWithSse
            String sessionId = UUID.randomUUID().toString();
            
            // 构建会话数据
            Map<String, Object> sessionData = new HashMap<>();
            sessionData.put("agentId", originalMessage.getAgentID());
            sessionData.put("conversationId", originalMessage.getConversationID());
            sessionData.put("query", userQuestion.getContent());
            sessionData.put("filesData", null);  // 重新生成不需要传文件
            sessionData.put("createTime", System.currentTimeMillis());
            
            // 存入Redis，5分钟过期
            String redisKey = CHAT_SESSION_PREFIX + sessionId;
            redisTemplate.opsForValue().set(redisKey, sessionData, 5, TimeUnit.MINUTES);
            
            log.info("重新生成回答: messageId={}, sessionId={}", messageId, sessionId);
            return streamChatWithSse(sessionId);
            
        } catch (Exception e) {
            log.error("重新生成回答异常", e);
            try {
                emitter.send(SseEmitter.event().name("error").data(e.getMessage()));
                emitter.completeWithError(e);
            } catch (IOException ex) {
                log.error("发送异常事件失败", ex);
                emitter.completeWithError(ex);
            }
            return emitter;
        }
    }

    @Override
    public ResultDomain<Boolean> generateSummaryAsync(String conversationId) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            // 异步生成摘要
            CompletableFuture.runAsync(() -> {
                try {
                    // 查询会话的所有消息
                    List<TbAiMessage> messages = messageMapper.selectMessagesByConversationId(conversationId);
                    
                    if (messages.size() < 2) {
                        log.info("会话消息过少，无需生成摘要: {}", conversationId);
                        return;
                    }

                    // 提取对话内容生成摘要（简单实现：取第一个用户问题）
                    String summary = messages.stream()
                            .filter(m -> "user".equals(m.getRole()))
                            .findFirst()
                            .map(TbAiMessage::getContent)
                            .orElse("对话");

                    // 限制长度
                    if (summary.length() > 50) {
                        summary = summary.substring(0, 50) + "...";
                    }

                    // 更新会话摘要
                    TbAiConversation update = new TbAiConversation();
                    update.setID(conversationId);
                    update.setSummary(summary);
                    update.setUpdateTime(new Date());
                    conversationMapper.updateConversation(update);

                    log.info("会话摘要生成成功: {} - {}", conversationId, summary);

                } catch (Exception e) {
                    log.error("生成会话摘要失败: {}", conversationId, e);
                }
            }, executorService);

            resultDomain.success("摘要生成任务已提交", true);
            return resultDomain;

        } catch (Exception e) {
            log.error("提交摘要生成任务异常", e);
            resultDomain.fail("提交任务异常: " + e.getMessage());
            return resultDomain;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDomain<Boolean> rateMessage(String messageId, Integer rating, String feedback) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();

        try {
            if (!StringUtils.hasText(messageId)) {
                resultDomain.fail("消息ID不能为空");
                return resultDomain;
            }

            TbAiMessage message = messageMapper.selectMessageById(messageId);
            if (message == null || message.getDeleted()) {
                resultDomain.fail("消息不存在");
                return resultDomain;
            }

            // 获取智能体配置（需要API Key）
            TbAiAgentConfig agent = agentConfigMapper.selectAgentConfigById(message.getAgentID());
            if (agent == null) {
                resultDomain.fail("智能体不存在");
                return resultDomain;
            }

            // 获取当前用户
            TbSysUser currentUser = LoginUtil.getCurrentUser();
            if (currentUser == null) {
                resultDomain.fail("用户未登录");
                return resultDomain;
            }

            // 如果有Dify消息ID，同步反馈到Dify
            if (StringUtils.hasText(message.getDifyMessageId())) {
                try {
                    // 将评分转换为Dify格式：1=like, -1=dislike, 0=null
                    String difyRating = null;
                    if (rating != null) {
                        if (rating > 0) {
                            difyRating = "like";
                        } else if (rating < 0) {
                            difyRating = "dislike";
                        }
                        // rating == 0 时，difyRating 为 null（取消评价）
                    }

                    difyApiClient.submitMessageFeedback(
                            message.getDifyMessageId(),
                            difyRating,
                            currentUser.getID(),
                            feedback,
                            agent.getDifyApiKey()
                    );
                    log.info("Dify消息反馈提交成功: {} - {}", message.getDifyMessageId(), difyRating);
                } catch (DifyException e) {
                    log.error("提交Dify反馈失败", e);
                    // 不影响本地评价，继续执行
                }
            }

            // 更新本地评价
            TbAiMessage update = new TbAiMessage();
            update.setID(messageId);
            update.setRating(rating);
            update.setFeedback(feedback);
            update.setUpdateTime(new Date());
            messageMapper.updateMessage(update);

            log.info("消息评价成功: {} - 评分: {}", messageId, rating);
            resultDomain.success("评价成功", true);
            return resultDomain;

        } catch (Exception e) {
            log.error("评价消息异常", e);
            resultDomain.fail("评价异常: " + e.getMessage());
            return resultDomain;
        }
    }

    /**
     * 保存消息关联的文件记录
     * @param messageId 消息ID
     * @param conversationId 会话ID
     * @param userId 用户ID
     * @param filesData 文件数据列表
     */
    private void saveMessageFileRecords(String messageId, String conversationId, String userId, List<DifyFileInfo> filesData) {
        try {
            List<TbAiUploadFile> fileRecords = new ArrayList<>();
            Date now = new Date();
            
            for (DifyFileInfo fileInfo : filesData) {
                TbAiUploadFile uploadFile = new TbAiUploadFile();
                uploadFile.setID(UUID.randomUUID().toString());
                uploadFile.setUserID(userId);
                uploadFile.setConversationID(conversationId);
                uploadFile.setMessageID(messageId);  // 绑定到消息
                
                // 从文件信息中提取系统文件ID（前端传递sys_file_id字段）
                uploadFile.setSysFileId(fileInfo.getSysFileId());
                
                uploadFile.setFileName(fileInfo.getName());
                uploadFile.setFilePath(fileInfo.getFilePath() != null ? fileInfo.getFilePath() : "");  // 从系统文件表获取的文件路径
                uploadFile.setFileSize(fileInfo.getSize() != null ? fileInfo.getSize().longValue() : 0L);
                uploadFile.setFileType(fileInfo.getExtension());
                uploadFile.setMimeType(fileInfo.getMimeType());
                uploadFile.setDifyUploadFileId(fileInfo.getUploadFileId());  // Dify的上传文件ID
                uploadFile.setStatus(2);  // 已完成（对话文件直接可用）
                uploadFile.setCreateTime(now);
                uploadFile.setUpdateTime(now);
                uploadFile.setDeleted(false);
                
                fileRecords.add(uploadFile);
            }
            
            if (!fileRecords.isEmpty()) {
                uploadFileMapper.batchInsertUploadFiles(fileRecords);
                log.info("消息文件记录已保存: messageId={}, fileCount={}", messageId, fileRecords.size());
            }
        } catch (Exception e) {
            log.error("保存消息文件记录失败: messageId={}", messageId, e);
            // 不抛出异常，不影响主流程
        }
    }
    
    /**
     * 根据用户获取可访问的知识库ID列表（基于部门路径）
     * @param user 当前用户
     * @return 知识库ID列表
     */
    private List<String> getKnowledgeIdsByUser(TbSysUser user) {
        try {
            // 获取当前登录用户的完整信息（包含部门角色列表）
            LoginDomain loginDomain = LoginUtil.getCurrentLoginDomain();
            if (loginDomain == null || loginDomain.getRoles() == null || loginDomain.getRoles().isEmpty()) {
                log.warn("用户 {} 没有部门角色信息，返回空知识库列表", user.getID());
                return null;
            }

            // 获取用户的第一个部门角色（通常用户属于一个主部门）
            UserDeptRoleVO userRole = loginDomain.getRoles().get(0);
            String deptPath = userRole.getDeptPath();
            
            if (deptPath == null || deptPath.isEmpty()) {
                log.warn("用户 {} 的部门路径为空，返回空知识库列表", user.getID());
                return null;
            }

            // 根据部门路径获取知识库ID列表（包含父部门的知识库）
            List<String> knowledgeIds = ((AiKnowledgeRedisServiceImpl) knowledgeRedisService).getKnowledgeIdsByDeptPath(deptPath);
            
            if (knowledgeIds == null || knowledgeIds.isEmpty()) {
                log.warn("用户 {} 所在部门路径 {} 没有关联的知识库", user.getID(), deptPath);
                return null;
            }

            log.info("用户 {} 从部门路径 {} 获取到 {} 个知识库", user.getID(), deptPath, knowledgeIds.size());
            return knowledgeIds;

        } catch (Exception e) {
            log.error("根据用户获取知识库ID失败: userId={}", user.getID(), e);
            return null;
        }
    }
}

