package com.emotion.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.emotion.entity.Message;
import com.emotion.entity.Conversation;
import com.emotion.entity.CozeApiCall;
import com.emotion.entity.EmotionRecord;
import com.emotion.entity.EmotionAnalysis;
import com.emotion.service.AiChatService;
import com.emotion.service.MessageService;
import com.emotion.service.ConversationService;
import com.emotion.service.CozeApiCallService;
import com.emotion.service.EmotionRecordService;
import com.emotion.service.EmotionAnalysisService;
import com.emotion.service.AiConfigService;
import com.emotion.entity.AiConfig;
import com.emotion.dto.request.*;
import com.emotion.dto.response.*;
import com.emotion.util.SnowflakeIdGenerator;
import com.emotion.util.UserContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.scheduling.annotation.Async;
import java.util.concurrent.CompletableFuture;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * AI聊天服务实现类
 * 
 * @author huazhongmin
 * @date 2025-07-24
 */
@Slf4j
@Service
public class AiChatServiceImpl implements AiChatService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MessageService messageService;

    @Autowired
    private ConversationService conversationService;

    @Autowired
    private CozeApiCallService cozeApiCallService;

    @Autowired
    private EmotionRecordService emotionRecordService;

    @Autowired
    private EmotionAnalysisService emotionAnalysisService;

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    @Autowired
    private AiConfigService aiConfigService;

    private static final String DEFAULT_USER_ID = "emotion-museum-user";

    // 使用场景常量
    private static final String USAGE_SCENARIO_CHAT = "chat";
    private static final String USAGE_SCENARIO_SUMMARY = "summary";
    private static final String DEFAULT_ENVIRONMENT = "production";

    /**
     * Coze工作流配置键 - 聊天场景
     */
    private static final String COZE_CHAT_CONFIG_KEY = "coze.chat.default";

    // API 相关常量
    private static final String CONTENT_KEY = "content";
    private static final String ROLE_KEY = "role";
    private static final String USER_ROLE = "user";
    private static final String ASSISTANT_ROLE = "assistant";
    private static final String CONTENT_TYPE_KEY = "content_type";
    private static final String TEXT_TYPE = "text";
    private static final String ANSWER_TYPE = "answer";
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public AiChatResponse sendChatMessage(AiChatRequest request) {
        log.info("发送聊天消息: conversationId={}, userId={}, message={}",
                request.getConversationId(), request.getUserId(), request.getMessage());

        try {
            // 先保存用户消息
            Message userMessage = new Message();
            userMessage.setId(snowflakeIdGenerator.nextIdAsString());
            userMessage.setConversationId(request.getConversationId());
            userMessage.setCreateBy(request.getUserId());
            userMessage.setContent(request.getMessage());
            userMessage.setType("text");
            userMessage.setSender("user");
            userMessage = messageService.createMessage(userMessage);

            // 调用Coze API（传入messageId）
            String aiReply = sendMessageWithMessageId(request.getConversationId(), userMessage.getId(),
                    request.getMessage(), request.getUserId());

            // 保存AI回复
            Message aiMessage = new Message();
            aiMessage.setId(snowflakeIdGenerator.nextIdAsString());
            aiMessage.setConversationId(request.getConversationId());
            aiMessage.setCreateBy("ai");
            aiMessage.setContent(aiReply);
            aiMessage.setType("text");
            aiMessage.setSender("ai");
            aiMessage = messageService.createMessage(aiMessage);

            log.info("聊天消息处理完成: userMessageId={}, aiMessageId={}",
                    userMessage.getId(), aiMessage.getId());

            // 构建响应
            AiChatResponse response = new AiChatResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setConversationId(request.getConversationId());
            response.setUserMessage(request.getMessage());
            response.setAiReply(aiReply);
            response.setUserId(request.getUserId());
            response.setTimestamp(System.currentTimeMillis());

            return response;

        } catch (Exception e) {
            log.error("发送聊天消息失败", e);
            // 构建错误响应
            AiChatResponse response = new AiChatResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setConversationId(request.getConversationId());
            response.setUserMessage(request.getMessage());
            response.setAiReply("抱歉，AI服务暂时不可用，请稍后再试。");
            response.setUserId(request.getUserId());
            response.setTimestamp(System.currentTimeMillis());
            return response;
        }
    }

    @Override
    public AiSummaryResponse generateConversationSummary(AiSummaryRequest request) {
        log.info("生成对话总结: conversationId={}, userId={}", request.getConversationId(), request.getUserId());

        try {
            // 获取对话历史
            String conversationHistory = getConversationHistory(request.getConversationId());

            // 构建总结请求
            String summaryPrompt = "请为以下对话生成一个简洁的总结：\n\n" + conversationHistory;

            // 调用AI生成总结 - 使用专门的总结bot
            String summary = sendSummaryMessage(request.getConversationId(), summaryPrompt, request.getUserId());

            log.info("对话总结生成完成: conversationId={}", request.getConversationId());

            // 构建响应
            AiSummaryResponse response = new AiSummaryResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setConversationId(request.getConversationId());
            response.setSummary(summary);
            response.setUserId(request.getUserId());
            response.setTimestamp(System.currentTimeMillis());

            return response;

        } catch (Exception e) {
            log.error("生成对话总结失败", e);
            // 构建错误响应
            AiSummaryResponse response = new AiSummaryResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setConversationId(request.getConversationId());
            response.setSummary("无法生成对话总结，请稍后再试。");
            response.setUserId(request.getUserId());
            response.setTimestamp(System.currentTimeMillis());
            return response;
        }
    }

    @Override
    public AiStatusResponse getServiceStatus() {
        log.info("获取AI服务状态");

        boolean available = isServiceAvailable();

        // 构建响应
        AiStatusResponse response = new AiStatusResponse();
        response.setId(snowflakeIdGenerator.nextIdAsString());
        response.setAvailable(available);
        response.setStatus(available ? "available" : "unavailable");
        response.setTimestamp(System.currentTimeMillis());

        return response;
    }

    @Override
    public ChatStatsResponse getChatStats(ChatStatsRequest request) {
        log.info("获取聊天统计: userId={}, conversationId={}", request.getUserId(), request.getConversationId());

        // 构建响应
        ChatStatsResponse response = new ChatStatsResponse();
        response.setId(snowflakeIdGenerator.nextIdAsString());

        if (request.getUserId() != null && !request.getUserId().trim().isEmpty()) {
            Long userConversationCount = conversationService.countByUserId(request.getUserId());
            Long activeConversationCount = conversationService.countActiveByUserId(request.getUserId());

            response.setUserConversationCount(userConversationCount);
            response.setActiveConversationCount(activeConversationCount);
        }

        if (request.getConversationId() != null && !request.getConversationId().trim().isEmpty()) {
            Long conversationMessageCount = messageService.countByConversationId(request.getConversationId());
            response.setConversationMessageCount(conversationMessageCount);
        }

        response.setTimestamp(System.currentTimeMillis());

        return response;
    }

    @Override
    public GuestChatResponse guestChat(GuestChatRequest request, String clientIp) {
        log.info("访客聊天: message={}, clientIp={}", request.getMessage(), clientIp);

        try {
            // 生成访客会话ID
            String guestConversationId = "guest_" + clientIp.replace(".", "_") + "_" + System.currentTimeMillis();

            // 调用AI服务
            String aiReply = sendMessage(guestConversationId, request.getMessage(), "guest");

            // 保存访客消息
            Message guestMessage = new Message();
            guestMessage.setId(snowflakeIdGenerator.nextIdAsString());
            guestMessage.setConversationId(guestConversationId);
            guestMessage.setCreateBy("guest");
            guestMessage.setContent(request.getMessage());
            guestMessage.setType("text");
            guestMessage.setSender("guest");
            guestMessage = messageService.createMessage(guestMessage);

            // 保存AI回复
            Message aiMessage = new Message();
            aiMessage.setId(snowflakeIdGenerator.nextIdAsString());
            aiMessage.setConversationId(guestConversationId);
            aiMessage.setCreateBy("ai");
            aiMessage.setContent(aiReply);
            aiMessage.setType("text");
            aiMessage.setSender("ai");
            aiMessage = messageService.createMessage(aiMessage);

            // 构建响应
            GuestChatResponse response = new GuestChatResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setMessage(aiReply);
            response.setMessageId(aiMessage.getId());
            response.setTimestamp(System.currentTimeMillis());
            response.setError(false);

            log.info("访客聊天处理完成: guestMessageId={}, aiMessageId={}",
                    guestMessage.getId(), aiMessage.getId());

            return response;

        } catch (Exception e) {
            log.error("访客聊天失败", e);
            // 构建错误响应
            GuestChatResponse response = new GuestChatResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setMessage("抱歉，服务暂时不可用，请稍后再试。");
            response.setMessageId(null);
            response.setTimestamp(System.currentTimeMillis());
            response.setError(true);
            return response;
        }
    }

    @Override
    public GuestUserInfoResponse getGuestUserInfo(String clientIp) {
        log.info("获取访客用户信息: clientIp={}", clientIp);

        try {
            // 生成访客用户信息
            String guestId = "guest_" + clientIp.replace(".", "_");
            String guestUsername = "访客_" + clientIp.substring(clientIp.lastIndexOf(".") + 1);

            // 构建响应
            GuestUserInfoResponse response = new GuestUserInfoResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setId(guestId);
            response.setUsername(guestUsername);
            response.setNickname(guestUsername);
            response.setType("guest");
            response.setClientIp(clientIp);
            response.setUserCreateTime(System.currentTimeMillis());

            log.info("访客用户信息获取成功: guestId={}", guestId);

            return response;

        } catch (Exception e) {
            log.error("获取访客用户信息失败", e);
            // 构建错误响应
            GuestUserInfoResponse response = new GuestUserInfoResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setId("error");
            response.setUsername("访客用户");
            response.setNickname("访客用户");
            response.setType("guest");
            response.setClientIp(clientIp);
            response.setUserCreateTime(System.currentTimeMillis());
            return response;
        }
    }

    @Override
    public ConversationResponse createConversation(ConversationCreateRequest request, String clientIp) {
        log.info("创建对话: userId={}, title={}", request.getUserId(), request.getTitle());

        try {
            // 调用AI服务创建对话
            Map<String, Object> aiConversation = createConversation(request.getUserId(), request.getTitle());

            // 创建数据库对话记录
            Conversation conversation = conversationService.createConversation(
                    request.getUserId(),
                    request.getTitle(),
                    request.getType() != null ? request.getType() : "user");

            // 构建响应
            ConversationResponse response = new ConversationResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setUserId(conversation.getUserId());
            response.setCozeConversationId(conversation.getCozeConversationId());
            response.setTitle(conversation.getTitle());
            response.setType(conversation.getType());
            response.setStatus(conversation.getConversationStatus());
            response.setMessageCount(conversation.getMessageCount());
            if (conversation.getLastActiveTime() != null) {
                response.setLastMessageTime(conversation.getLastActiveTime().format(DATE_TIME_FORMATTER));
            }
            response.setClientIp(clientIp);

            if (conversation.getCreateTime() != null) {
                response.setCreateTime(conversation.getCreateTime().format(DATE_TIME_FORMATTER));
            }
            if (conversation.getUpdateTime() != null) {
                response.setUpdateTime(conversation.getUpdateTime().format(DATE_TIME_FORMATTER));
            }

            log.info("对话创建成功: conversationId={}", conversation.getId());

            return response;

        } catch (Exception e) {
            log.error("创建对话失败", e);
            // 构建错误响应
            ConversationResponse response = new ConversationResponse();
            response.setId(snowflakeIdGenerator.nextIdAsString());
            response.setUserId(request.getUserId());
            response.setTitle(request.getTitle());
            response.setType(request.getType() != null ? request.getType() : "user");
            response.setStatus("error");
            response.setMessageCount(0);
            response.setLastMessageTime("");
            response.setClientIp(clientIp);
            return response;
        }
    }

    @Override
    public String sendChatMessageForWebSocket(String conversationId, String message, String userId) {
        log.info("WebSocket发送聊天消息: conversationId={}, userId={}, message={}", conversationId, userId, message);

        try {
            // 调用Coze API（不带messageId）
            String aiReply = sendMessage(conversationId, message, userId);

            // 注意：不保存用户消息，因为WebSocket处理器已经保存了
            // 只保存AI回复
            Message aiMessage = new Message();
            aiMessage.setId(snowflakeIdGenerator.nextIdAsString());
            aiMessage.setConversationId(conversationId);
            aiMessage.setCreateBy("ai");
            aiMessage.setContent(aiReply);
            aiMessage.setType("text");
            aiMessage.setSender("ai");
            aiMessage = messageService.createMessage(aiMessage);

            log.info("WebSocket聊天消息处理完成: aiMessageId={}", aiMessage.getId());

            return aiReply;

        } catch (Exception e) {
            log.error("WebSocket发送聊天消息失败", e);
            return "抱歉，我暂时无法回复，请稍后再试。";
        }
    }

    @Override
    public String sendChatMessageForWebSocket(String conversationId, String messageId, String message, String userId) {
        log.info("WebSocket发送聊天消息（带messageId）: conversationId={}, messageId={}, userId={}, message={}",
                conversationId, messageId, userId, message);

        try {
            // 调用Coze API（带messageId）
            String aiReply = sendMessageWithMessageId(conversationId, messageId, message, userId);

            // 注意：不在这里保存AI回复消息
            // WebSocket处理器会在sendAiReplyInParts中分割并保存每条消息
            // 这样可以确保分割后的消息都被正确保存到数据库

            log.info("WebSocket聊天消息处理完成（带messageId）: userMessageId={}, aiReplyLength={}",
                    messageId, aiReply != null ? aiReply.length() : 0);

            return aiReply;

        } catch (Exception e) {
            log.error("WebSocket发送聊天消息失败（带messageId）", e);
            return "抱歉，我暂时无法回复，请稍后再试。";
        }
    }

    @Override
    public String sendMessage(String conversationId, String userMessage, String userId) {
        log.info("发送消息到Coze AI: conversationId={}, userId={}", conversationId, userId);

        // 创建API调用记录（不包含messageId，用于向后兼容）
        CozeApiCall apiCall = createApiCallRecord(conversationId, null, userMessage, userId, "chat");

        try {
            return executeCozeApiCall(apiCall, conversationId, userMessage, userId);
        } catch (Exception e) {
            log.error("发送消息失败", e);
            updateApiCallFailure(apiCall, e.getMessage());
            return "抱歉，AI服务暂时不可用，请稍后再试。";
        }
    }

    @Override
    public String streamChat(String conversationId, String message, String userId) {
        log.info("流式聊天: conversationId={}, userId={}", conversationId, userId);

        try {
            // 构建流式请求
            Map<String, Object> requestBody = buildCozeRequest(conversationId, message, userId);
            requestBody.put("stream", true);

            // 这里应该实现流式处理，暂时降级到普通聊天
            return sendMessage(conversationId, message, userId);

        } catch (Exception e) {
            log.error("流式聊天失败", e);
            return "抱歉，流式聊天暂时不可用，请稍后再试。";
        }
    }

    @Override
    public boolean healthCheck() {
        try {
            // 检查聊天场景的AI配置是否存在
            AiConfig chatConfig = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
            if (chatConfig == null) {
                log.warn("未找到聊天场景的AI配置");
                return false;
            }

            // 检查必要配置是否完整
            boolean configValid = chatConfig.getApiToken() != null && !chatConfig.getApiToken().trim().isEmpty() &&
                    chatConfig.getBotId() != null && !chatConfig.getBotId().trim().isEmpty() &&
                    chatConfig.getApiBaseUrl() != null && !chatConfig.getApiBaseUrl().trim().isEmpty();

            if (!configValid) {
                log.warn("AI配置不完整: configId={}", chatConfig.getId());
                return false;
            }

            // 可选：发送一个简单的测试请求
            // 这里可以调用一个轻量级的API来验证连接
            return true;

        } catch (Exception e) {
            log.error("健康检查失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public Map<String, Object> generateEmotionSummary(String userId) {
        log.info("生成用户情绪记录总结: userId={}", userId);

        Map<String, Object> result = new HashMap<>();

        try {
            // 获取用户当天的所有聊天记录
            LocalDate today = LocalDate.now();
            LocalDateTime startOfDay = today.atStartOfDay();
            LocalDateTime endOfDay = today.atTime(23, 59, 59);

            List<Message> todayMessages = messageService.getByUserIdAndTimeRange(userId, startOfDay, endOfDay);
            log.info("获取到用户当天聊天记录数量: {}", todayMessages.size());

            if (todayMessages.isEmpty()) {
                result.put("success", false);
                result.put("message", "今天还没有聊天记录，无法生成情绪总结");
                return result;
            }

            // 整合聊天记录
            String chatHistory = integrateChatHistory(todayMessages);
            log.info("聊天记录整合完成，总长度: {}", chatHistory.length());

            // Coze 中已经在工作流设置了提示词，目前不需要构建情绪分析提示词
            // String emotionPrompt = buildEmotionAnalysisPrompt(chatHistory);

            // 调用Coze API进行情绪分析总结
            String conversationId = "emotion_summary_" + userId + "_"
                    + today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String emotionSummary = sendSummaryMessage(conversationId, chatHistory, userId);
            log.info("情绪分析总结生成完成: {}", emotionSummary);

            // 解析AI返回的情绪分析结果
            EmotionAnalysis analysisResult = parseEmotionSummary(emotionSummary);

            // 创建情绪记录
            EmotionRecord emotionRecord = createEmotionRecord(userId, analysisResult, chatHistory);

            result.put("success", true);
            result.put("emotionRecord", emotionRecord);
            result.put("summary", emotionSummary);
            result.put("analysisResult", analysisResult);
            result.put("messageCount", todayMessages.size());
            result.put("recordDate", today);

            log.info("情绪记录总结生成成功: recordId={}", emotionRecord.getId());

        } catch (Exception e) {
            log.error("生成情绪记录总结失败", e);
            result.put("success", false);
            result.put("message", "生成情绪总结失败: " + e.getMessage());
        }

        return result;
    }

    @Override
    @Async("taskExecutor")
    public CompletableFuture<Map<String, Object>> generateEmotionSummaryAsync(String userId) {
        Map<String, Object> result = generateEmotionSummary(userId);
        return CompletableFuture.completedFuture(result);
    }

    @Override
    public String sendSummaryMessage(String conversationId, String userMessage, String userId) {
        log.info("发送总结消息到Coze AI: conversationId={}, userId={}", conversationId, userId);

        // 创建API调用记录（总结不需要messageId）
        CozeApiCall apiCall = createSummaryApiCallRecord(conversationId, null, userMessage, userId, "summary");

        try {
            return executeSummaryCozeApiCall(apiCall, conversationId, userMessage, userId);
        } catch (Exception e) {
            log.error("发送总结消息失败", e);
            updateApiCallFailure(apiCall, e.getMessage());
            return "抱歉，AI总结服务暂时不可用，请稍后再试。";
        }
    }

    /**
     * 执行总结Coze API调用的逻辑
     */
    private String executeSummaryCozeApiCall(CozeApiCall apiCall, String conversationId, String userMessage, String userId) {
        // 获取总结场景的AI配置
        AiConfig config = getSummaryAiConfig();
        
        // 构建请求体 - 使用总结专用的bot和workflow
        Map<String, Object> requestBody = buildSummaryRequest(conversationId, userMessage, userId);
        
        // 检查是否使用流式输出
        boolean useStream = (Boolean) requestBody.get("stream");
        
        if (useStream) {
            return executeStreamCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
        } else {
            return executeSummaryNormalCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
        }
    }

    /**
     * 执行普通（非流式）总结Coze API调用
     */
    private String executeSummaryNormalCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody,
                                                 String conversationId, String userMessage, String userId) {
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiToken());
        headers.set("Content-Type", "application/json");

        // 构建完整的API URL
        String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
        
        // 更新API调用记录的请求信息
        updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        log.info("发送Coze总结请求到: {}, 请求体: {}", cozeApiUrl, requestBody);

        // 发送请求
        ResponseEntity<String> response = restTemplate.exchange(
                cozeApiUrl,
                HttpMethod.POST,
                request,
                String.class);

        log.info("收到Coze总结初始响应: {}", response.getBody());

        // 更新API调用记录的响应信息
        updateApiCallResponse(apiCall, response);

        // 解析响应获取chat_id和conversation_id
        JSONObject responseJson = JSON.parseObject(response.getBody());
        String chatId = extractChatIdFromResponse(responseJson);
        String cozeConversationId = extractConversationIdFromResponse(responseJson);

        if (chatId != null && cozeConversationId != null) {
            // 更新API调用记录的Coze ID信息
            updateApiCallCozeIds(apiCall, chatId, cozeConversationId);

            // 轮询聊天状态直到完成并获取回复内容
            String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
            log.info("Coze AI总结响应成功: reply={}", aiReply);

            // 更新API调用记录的最终结果
            updateApiCallSuccess(apiCall, aiReply);

            return aiReply;
        } else {
            log.error("无法从Coze总结响应中获取chat_id或conversation_id");
            updateApiCallError(apiCall, "INVALID_RESPONSE", "无法从Coze总结响应中获取chat_id或conversation_id");
            return "抱歉，AI总结服务响应异常，请稍后再试。";
        }
    }

    @Override
    public EmotionSummaryGenerateResponse generateEmotionSummaryWithResponse(String userId) {
        log.info("生成用户情绪记录总结: userId={}", userId);

        // 调用原有的generateEmotionSummary方法
        Map<String, Object> result = generateEmotionSummary(userId);

        // 转换为响应对象
        return convertToGenerateResponse(result);
    }

    @Override
    public EmotionSummaryStatusResponse getEmotionSummaryStatusWithResponse(String userId) {
        log.info("获取用户情绪记录总结状态: userId={}", userId);

        // 构建状态信息
        Map<String, Object> statusInfo = Map.of(
                "userId", userId,
                "canGenerate", true,
                "message", "可以生成情绪记录总结");

        // 转换为响应对象
        return convertToStatusResponse(statusInfo);
    }

    /**
     * 转换为生成响应对象
     */
    private EmotionSummaryGenerateResponse convertToGenerateResponse(Map<String, Object> result) {
        EmotionSummaryGenerateResponse response = new EmotionSummaryGenerateResponse();
        response.setSuccess((Boolean) result.get("success"));
        response.setMessage((String) result.get("message"));

        if (result.containsKey("emotionRecord") && result.get("emotionRecord") != null) {
            // 从实际的EmotionRecord对象获取ID
            Object emotionRecord = result.get("emotionRecord");
            if (emotionRecord instanceof EmotionRecord) {
                response.setEmotionRecordId(((EmotionRecord) emotionRecord).getId());
            }
        }

        if (result.containsKey("analysisResult") && result.get("analysisResult") != null) {
            // 从实际的EmotionAnalysis对象获取ID
            Object analysisResult = result.get("analysisResult");
            if (analysisResult instanceof EmotionAnalysis) {
                response.setEmotionAnalysisId(((EmotionAnalysis) analysisResult).getId());
            }
        }

        if (result.containsKey("messageCount")) {
            response.setMessageCount((Integer) result.get("messageCount"));
        }

        if (result.containsKey("recordDate")) {
            response.setRecordDate(result.get("recordDate").toString());
        }

        return response;
    }

    /**
     * 转换为状态响应对象
     */
    private EmotionSummaryStatusResponse convertToStatusResponse(Map<String, Object> statusInfo) {
        EmotionSummaryStatusResponse response = new EmotionSummaryStatusResponse();
        response.setUserId((String) statusInfo.get("userId"));
        response.setCanGenerate((Boolean) statusInfo.get("canGenerate"));
        response.setMessage((String) statusInfo.get("message"));
        return response;
    }

    public boolean isServiceAvailable() {
        try {
            // 检查聊天场景的AI配置是否可用
            AiConfig chatConfig = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
            return chatConfig != null && 
                   chatConfig.getApiToken() != null && !chatConfig.getApiToken().isEmpty() &&
                   chatConfig.getBotId() != null && !chatConfig.getBotId().isEmpty();
        } catch (Exception e) {
            log.error("检查AI服务可用性失败", e);
            return false;
        }
    }

    /**
     * 发送消息到Coze AI（带messageId）
     * 使用通用工作流调用方式，通过配置键获取AI配置
     *
     * @param conversationId 会话ID
     * @param messageId 消息ID
     * @param userMessage 用户消息
     * @param userId 用户ID
     * @return AI回复内容
     */
    private String sendMessageWithMessageId(String conversationId, String messageId, String userMessage,
            String userId) {
        log.info("发送消息到Coze AI: conversationId={}, messageId={}, userId={}", conversationId, messageId, userId);

        // 1. 获取AI配置
        AiConfig config = aiConfigService.getByConfigKey(COZE_CHAT_CONFIG_KEY);
        if (config == null) {
            log.error("未找到聊天场景的AI配置或配置已禁用: configKey={}", COZE_CHAT_CONFIG_KEY);
            return "抱歉，AI服务暂时不可用，请稍后再试。";
        }

        // 2. 创建API调用记录（包含conversationId和messageId）
        CozeApiCall apiCall = createChatWorkflowApiCallRecord(config, conversationId, messageId, userMessage, userId);

        try {
            // 3. 构建工作流请求参数
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("input", userMessage);
            parameters.put("user_id", userId);

            // 4. 构建工作流请求体
            Map<String, Object> requestBody = buildWorkflowRequest(config, parameters, userId);

            // 5. 执行工作流调用（带API调用记录）
            return executeWorkflowCallWithRecord(config, requestBody, COZE_CHAT_CONFIG_KEY, userId, apiCall);

        } catch (Exception e) {
            log.error("发送消息失败: conversationId={}, messageId={}, error={}",
                    conversationId, messageId, e.getMessage(), e);
            updateApiCallFailure(apiCall, e.getMessage());
            return "抱歉，AI服务暂时不可用，请稍后再试。";
        }
    }

    /**
     * 创建聊天工作流API调用记录（包含conversationId和messageId）
     *
     * @param config AI配置
     * @param conversationId 会话ID
     * @param messageId 消息ID
     * @param userMessage 用户消息
     * @param userId 用户ID
     * @return API调用记录
     */
    private CozeApiCall createChatWorkflowApiCallRecord(AiConfig config, String conversationId,
            String messageId, String userMessage, String userId) {
        CozeApiCall apiCall = CozeApiCall.builder()
                .id(snowflakeIdGenerator.nextIdAsString())
                .conversationId(conversationId)
                .messageId(messageId)
                .workflowId(config.getWorkflowId())
                .botId(config.getBotId())
                .userId(userId)
                .requestType("workflow")
                .userMessage(userMessage)
                .userMessageType("text")
                .status("pending")
                .startTime(LocalDateTime.now())
                .traceId(UUID.randomUUID().toString().replace("-", ""))
                .metadata(JSON.toJSONString(Map.of("configKey", COZE_CHAT_CONFIG_KEY)))
                .createBy(userId)
                .updateBy(userId)
                .build();

        // 获取客户端信息
        try {
            HttpServletRequest request = getCurrentRequest();
            if (request != null) {
                apiCall.setClientIp(getClientIp(request));
                apiCall.setUserAgent(request.getHeader("User-Agent"));
                apiCall.setSessionId(request.getSession().getId());
            }
        } catch (Exception e) {
            log.warn("获取客户端信息失败: {}", e.getMessage());
        }

        // 保存API调用记录
        cozeApiCallService.save(apiCall);
        log.info("创建聊天工作流API调用记录: id={}, conversationId={}, messageId={}, workflowId={}, traceId={}",
                apiCall.getId(), conversationId, messageId, config.getWorkflowId(), apiCall.getTraceId());

        return apiCall;
    }

    /**
     * 执行Coze API调用的公共逻辑
     */
    private String executeCozeApiCall(CozeApiCall apiCall, String conversationId, String userMessage, String userId) {
        // 获取聊天场景的AI配置
        AiConfig config = getChatAiConfig();
        
        // 构建请求体 - 使用正确的Coze API格式
        Map<String, Object> requestBody = buildCozeRequestWithConfig(conversationId, userMessage, userId, config);
        
        // 检查是否使用流式输出
        boolean useStream = (Boolean) requestBody.get("stream");
        
        if (useStream) {
            return executeStreamCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
        } else {
            return executeNormalCozeApiCall(apiCall, config, requestBody, conversationId, userMessage, userId);
        }
    }

    /**
     * 执行普通（非流式）Coze API调用
     */
    private String executeNormalCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody, 
                                          String conversationId, String userMessage, String userId) {
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiToken());
        headers.set("Content-Type", "application/json");

        // 构建完整的API URL
        String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
        
        // 更新API调用记录的请求信息
        updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        log.info("发送Coze普通请求到: {}, 请求体: {}", cozeApiUrl, requestBody);

        // 发送请求
        ResponseEntity<String> response = restTemplate.exchange(
                cozeApiUrl,
                HttpMethod.POST,
                request,
                String.class);

        log.info("收到Coze初始响应: {}", response.getBody());

        // 更新API调用记录的响应信息
        updateApiCallResponse(apiCall, response);

        // 解析响应获取chat_id和conversation_id
        JSONObject responseJson = JSON.parseObject(response.getBody());
        String chatId = extractChatIdFromResponse(responseJson);
        String cozeConversationId = extractConversationIdFromResponse(responseJson);

        if (chatId != null && cozeConversationId != null) {
            // 更新API调用记录的Coze ID信息
            updateApiCallCozeIds(apiCall, chatId, cozeConversationId);

            // 轮询聊天状态直到完成并获取回复内容
            String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
            log.info("Coze AI普通响应成功: reply={}", aiReply);

            // 更新API调用记录的最终结果
            updateApiCallSuccess(apiCall, aiReply);

            return aiReply;
        } else {
            log.error("无法从Coze响应中获取chat_id或conversation_id");
            updateApiCallError(apiCall, "INVALID_RESPONSE", "无法从Coze响应中获取chat_id或conversation_id");
            return "抱歉，AI服务响应异常，请稍后再试。";
        }
    }

    /**
     * 执行流式Coze API调用
     */
    private String executeStreamCozeApiCall(CozeApiCall apiCall, AiConfig config, Map<String, Object> requestBody,
                                          String conversationId, String userMessage, String userId) {
        try {
            
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + config.getApiToken());
            headers.set("Content-Type", "application/json");
            headers.set("Accept", "text/event-stream");

            // 构建完整的API URL
            String cozeApiUrl = config.getApiBaseUrl() + getApiPath(config);
            
            // 更新API调用记录的请求信息
            updateApiCallRequest(apiCall, cozeApiUrl, requestBody, headers);

            log.info("发送Coze流式请求到: {}", cozeApiUrl);
            log.info("请求头: {}", headers.toSingleValueMap());
            log.info("请求体: {}", JSON.toJSONString(requestBody));

            // 使用RestTemplate处理流式响应
            String streamResponse = handleStreamResponse(cozeApiUrl, headers, requestBody, apiCall);
            
            log.info("Coze AI流式响应完成: length={}", streamResponse != null ? streamResponse.length() : 0);

            // 更新API调用记录的最终结果
            updateApiCallSuccess(apiCall, streamResponse);

            return streamResponse;

        } catch (Exception e) {
            log.error("流式API调用失败", e);
            updateApiCallError(apiCall, "STREAM_ERROR", e.getMessage());
            return "抱歉，AI流式服务暂时不可用，请稍后再试。";
        }
    }

    /**
     * 处理流式响应
     */
    private String handleStreamResponse(String url, HttpHeaders headers, Map<String, Object> requestBody, CozeApiCall apiCall) {
        try {
            log.info("开始处理流式响应，URL: {}", url);
            
            // 创建HTTP客户端，增加更长的超时时间
            java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
                    .connectTimeout(java.time.Duration.ofSeconds(60))
                    .build();

            // 构建请求
            java.net.http.HttpRequest.Builder requestBuilder = java.net.http.HttpRequest.newBuilder()
                    .uri(java.net.URI.create(url))
                    .timeout(java.time.Duration.ofMinutes(10))
                    .POST(java.net.http.HttpRequest.BodyPublishers.ofString(JSON.toJSONString(requestBody)));

            // 添加请求头
            log.info("设置请求头:");
            headers.forEach((key, values) -> {
                if (values != null && !values.isEmpty()) {
                    String value = values.get(0);
                    requestBuilder.header(key, value);
                    log.info("  {}: {}", key, key.equals("Authorization") ? "Bearer ***" : value);
                }
            });

            java.net.http.HttpRequest request = requestBuilder.build();
            log.info("发送流式请求，请求体: {}", JSON.toJSONString(requestBody));

            // 发送请求并处理流式响应
            StringBuilder responseBuilder = new StringBuilder();
            StringBuilder fullStreamData = new StringBuilder();
            String currentEvent = null;
            boolean hasReceivedData = false;
            
            java.net.http.HttpResponse<java.util.stream.Stream<String>> response = client.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofLines());

            log.info("流式响应状态码: {}", response.statusCode());

            if (response.statusCode() != 200) {
                String errorBody = response.body().collect(java.util.stream.Collectors.joining("\n"));
                log.error("流式请求失败，状态码: {}, 响应: {}", response.statusCode(), errorBody);
                updateApiCallError(apiCall, "HTTP_ERROR", "流式请求失败，状态码: " + response.statusCode());
                return handleNonStreamFallback(url, headers, requestBody, apiCall);
            }

            // 处理流式数据 - 正确处理SSE格式
            java.util.Iterator<String> lineIterator = response.body().iterator();
            while (lineIterator.hasNext()) {
                String line = lineIterator.next();
                fullStreamData.append(line).append("\n");
                
                if (line.trim().isEmpty()) {
                    // 空行表示事件结束，重置当前事件
                    currentEvent = null;
                    continue;
                }
                
                // 处理SSE事件格式
                if (line.startsWith("event:")) {
                    currentEvent = line.substring(6).trim();
                    log.debug("当前事件类型: {}", currentEvent);
                } else if (line.startsWith("data:")) {
                    String data = line.substring(5).trim(); // 注意这里是5，因为"data:"后面可能没有空格
                    
                    // 检查是否为结束标记
                    if ("\"[DONE]\"".equals(data) || "[DONE]".equals(data)) {
                        log.info("收到流式响应结束标记");
                        break;
                    }
                    
                    // 跳过空数据
                    if (data.isEmpty()) {
                        continue;
                    }
                    
                    hasReceivedData = true;
                    log.debug("解析流式数据，事件: {}, 数据: {}", currentEvent, data);
                    
                    // 处理不同类型的事件
                    if ("conversation.message.delta".equals(currentEvent)) {
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            
                            // 提取content字段并检查类型
                            if (jsonData.containsKey("content") && jsonData.containsKey("type")) {
                                String messageType = jsonData.getString("type");
                                String content = jsonData.getString("content");
                                
                                // 只处理answer类型的消息内容
                                if ("answer".equals(messageType) && content != null && !content.trim().isEmpty()) {
                                    log.debug("提取增量内容: {}", content);
                                    // 解析content中的JSON，提取output字段
                                    String extractedContent = extractOutputFromContent(content);
                                    if (extractedContent != null) {
                                        responseBuilder.append(extractedContent);
                                    }
                                }
                            }
                            
                        } catch (Exception e) {
                            log.warn("解析增量消息数据失败: {}, 数据: {}", e.getMessage(), data);
                        }
                    } else if ("conversation.message.completed".equals(currentEvent)) {
                        // 处理完整消息事件，作为备用方案
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            
                            // 检查是否为answer类型的消息
                            if (jsonData.containsKey("type") && "answer".equals(jsonData.getString("type"))) {
                                String content = jsonData.getString("content");
                                if (content != null && !content.trim().isEmpty()) {
                                    // 如果增量方式没有获取到内容，使用完整消息作为备用
                                    if (responseBuilder.length() == 0) {
                                        log.info("使用完整消息内容作为备用: {}", content);
                                        // 解析content中的JSON，提取output字段
                                        String extractedContent = extractOutputFromContent(content);
                                        if (extractedContent != null) {
                                            responseBuilder.append(extractedContent);
                                        }
                                    }
                                    // 记录完整消息用于验证
                                    log.debug("完整消息内容: {}", content);
                                }
                            }
                            
                        } catch (Exception e) {
                            log.warn("解析完整消息数据失败: {}, 数据: {}", e.getMessage(), data);
                        }
                    } else if ("conversation.chat.failed".equals(currentEvent)) {
                        // 处理聊天失败事件
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            if (jsonData.containsKey("last_error")) {
                                JSONObject lastError = jsonData.getJSONObject("last_error");
                                String errorCode = lastError.getString("code");
                                String errorMsg = lastError.getString("msg");
                                log.error("Coze流式聊天失败: code={}, msg={}", errorCode, errorMsg);
                                
                                // 如果是参数错误，直接返回错误信息，不再尝试降级处理
                                if ("4000".equals(errorCode)) {
                                    updateApiCallError(apiCall, "COZE_PARAM_ERROR", "参数错误: " + errorMsg);
                                    return "抱歉，请求参数有误，请检查配置后重试。";
                                }
                            }
                        } catch (Exception e) {
                            log.warn("解析聊天失败数据失败: {}", e.getMessage());
                        }
                    } else if ("conversation.chat.created".equals(currentEvent)) {
                        // 记录聊天创建信息
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            String chatId = jsonData.getString("id");
                            String conversationId = jsonData.getString("conversation_id");
                            if (chatId != null && conversationId != null) {
                                updateApiCallCozeIds(apiCall, chatId, conversationId);
                                log.info("流式聊天创建成功，chatId: {}, conversationId: {}", chatId, conversationId);
                            }
                        } catch (Exception e) {
                            log.warn("解析聊天创建数据失败: {}", e.getMessage());
                        }
                    } else if ("conversation.chat.completed".equals(currentEvent)) {
                        // 记录聊天完成信息
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            log.info("流式聊天完成，状态: {}", jsonData.getString("status"));
                        } catch (Exception e) {
                            log.warn("解析聊天完成数据失败: {}", e.getMessage());
                        }
                    }
                }
            }

            // 记录完整的流式数据用于调试
            updateApiCallStreamData(apiCall, fullStreamData.toString());
            log.info("流式响应处理完成，提取内容长度: {}, 是否接收到数据: {}", responseBuilder.length(), hasReceivedData);

            String finalResponse = responseBuilder.toString();
            if (finalResponse.isEmpty()) {
                if (hasReceivedData) {
                    log.warn("流式响应处理完成但内容为空，可能是消息类型过滤导致");
                    // 尝试从完整流式数据中提取最后一个完整消息
                    String fallbackContent = extractContentFromStreamData(fullStreamData.toString());
                    if (fallbackContent != null && !fallbackContent.isEmpty()) {
                        log.info("从流式数据中提取到备用内容: {}", fallbackContent);
                        return fallbackContent;
                    }
                } else {
                    log.warn("流式响应未接收到任何数据");
                }
                
                log.warn("流式响应为空，尝试降级到非流式处理");
                return handleNonStreamFallback(url, headers, requestBody, apiCall);
            }

            return finalResponse;

        } catch (Exception e) {
            log.error("处理流式响应失败: {}", e.getMessage(), e);
            updateApiCallError(apiCall, "STREAM_PROCESSING_ERROR", e.getMessage());
            // 降级到非流式处理
            return handleNonStreamFallback(url, headers, requestBody, apiCall);
        }
    }
    
    /**
     * 从流式数据中提取内容（备用方案）
     */
    private String extractContentFromStreamData(String streamData) {
        try {
            // 查找最后一个conversation.message.completed事件
            String[] lines = streamData.split("\n");
            String lastCompletedContent = null;
            
            for (int i = 0; i < lines.length; i++) {
                String line = lines[i].trim();
                if ("event:conversation.message.completed".equals(line) && i + 1 < lines.length) {
                    String dataLine = lines[i + 1].trim();
                    if (dataLine.startsWith("data:")) {
                        String data = dataLine.substring(5).trim();
                        try {
                            JSONObject jsonData = JSON.parseObject(data);
                            if ("answer".equals(jsonData.getString("type"))) {
                                String content = jsonData.getString("content");
                                if (content != null && !content.trim().isEmpty()) {
                                    // 解析content中的JSON，提取output字段
                                    String extractedContent = extractOutputFromContent(content);
                                    if (extractedContent != null) {
                                        lastCompletedContent = extractedContent;
                                    }
                                }
                            }
                        } catch (Exception e) {
                            log.debug("解析备用内容失败: {}", e.getMessage());
                        }
                    }
                }
            }
            
            return lastCompletedContent;
        } catch (Exception e) {
            log.warn("从流式数据提取内容失败: {}", e.getMessage());
            return null;
        }
    }
    
    /**
     * 非流式处理降级方案
     */
    private String handleNonStreamFallback(String url, HttpHeaders headers, Map<String, Object> requestBody, CozeApiCall apiCall) {
        try {
            log.info("执行非流式降级处理");
            
            // 移除stream参数，改为非流式请求
            Map<String, Object> nonStreamBody = new HashMap<>(requestBody);
            nonStreamBody.put("stream", false);
            
            // 构建请求头（移除流式相关头）
            HttpHeaders nonStreamHeaders = new HttpHeaders();
            headers.forEach((key, values) -> {
                if (!"Accept".equals(key) || !"text/event-stream".equals(values.get(0))) {
                    nonStreamHeaders.put(key, values);
                }
            });
            nonStreamHeaders.set("Content-Type", "application/json");
            
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(nonStreamBody, nonStreamHeaders);
            log.info("发送非流式降级请求到: {}, 请求体: {}", url, JSON.toJSONString(nonStreamBody));

            // 发送请求
            ResponseEntity<String> response = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    request,
                    String.class);

            log.info("收到非流式降级响应状态: {}, 响应体: {}", response.getStatusCode(), response.getBody());
            
            // 更新API调用记录的响应信息
            updateApiCallResponse(apiCall, response);

            // 解析响应获取chat_id和conversation_id
            JSONObject responseJson = JSON.parseObject(response.getBody());
            String chatId = extractChatIdFromResponse(responseJson);
            String cozeConversationId = extractConversationIdFromResponse(responseJson);

            if (chatId != null && cozeConversationId != null) {
                // 更新API调用记录的Coze ID信息
                updateApiCallCozeIds(apiCall, chatId, cozeConversationId);

                // 轮询聊天状态直到完成并获取回复内容
                String aiReply = waitForChatCompletionWithTracking(chatId, cozeConversationId, apiCall);
                log.info("非流式降级处理成功: reply={}", aiReply);
                return aiReply;
            } else {
                log.error("非流式降级处理失败：无法从响应中获取chat_id或conversation_id，响应: {}", response.getBody());
                updateApiCallError(apiCall, "INVALID_RESPONSE", "无法从响应中获取chat_id或conversation_id");
                return "抱歉，AI服务响应异常，请稍后再试。";
            }
            
        } catch (Exception e) {
            log.error("非流式降级处理失败: {}", e.getMessage(), e);
            updateApiCallError(apiCall, "FALLBACK_ERROR", e.getMessage());
            return "抱歉，AI服务暂时不可用，请稍后再试。";
        }
    }

    /**
     * 更新API调用记录的流式数据
     */
    private void updateApiCallStreamData(CozeApiCall apiCall, String streamData) {
        try {
            // 将流式数据包装成有效的JSON格式存储
            Map<String, Object> streamDataWrapper = new HashMap<>();
            streamDataWrapper.put("type", "stream");
            streamDataWrapper.put("data", streamData);
            streamDataWrapper.put("timestamp", System.currentTimeMillis());
            
            String jsonStreamData = JSON.toJSONString(streamDataWrapper);
            apiCall.setResponseBody(jsonStreamData);
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("更新API调用记录流式数据失败: {}", e.getMessage(), e);
        }
    }

    public Map<String, Object> guestChat(String message, String clientIp) {
        log.info("访客聊天: message={}, clientIp={}", message, clientIp);

        Map<String, Object> result = new HashMap<>();

        try {
            // 生成访客会话ID
            String guestConversationId = "guest_" + clientIp.replace(".", "_") + "_" + System.currentTimeMillis();

            // 调用AI服务
            String aiReply = sendMessage(guestConversationId, message, "guest");

            // 保存访客消息
            Message guestMessage = new Message();
            guestMessage.setConversationId(guestConversationId);
            guestMessage.setCreateBy("guest");
            guestMessage.setContent(message);
            guestMessage.setType("text");
            guestMessage.setSender("guest");
            guestMessage = messageService.createMessage(guestMessage);

            // 保存AI回复
            Message aiMessage = new Message();
            aiMessage.setConversationId(guestConversationId);
            aiMessage.setCreateBy("ai");
            aiMessage.setContent(aiReply);
            aiMessage.setType("text");
            aiMessage.setSender("ai");
            aiMessage = messageService.createMessage(aiMessage);

            result.put("message", aiReply);
            result.put("messageId", aiMessage.getId());
            result.put("timestamp", System.currentTimeMillis());
            result.put("error", false);

            log.info("访客聊天处理完成: guestMessageId={}, aiMessageId={}",
                    guestMessage.getId(), aiMessage.getId());

        } catch (Exception e) {
            log.error("访客聊天失败", e);
            result.put("message", "抱歉，服务暂时不可用，请稍后再试。");
            result.put("messageId", null);
            result.put("timestamp", System.currentTimeMillis());
            result.put("error", true);
        }

        return result;
    }

    public Map<String, Object> createConversation(String userId, String title) {
        log.info("创建对话: userId={}, title={}", userId, title);

        Map<String, Object> result = new HashMap<>();

        try {
            // 调用数据库服务创建对话
            Conversation conversation = conversationService.createConversation(userId, title, "user");

            result.put("conversationId", conversation.getId());
            result.put("title", title);
            result.put("userId", userId);
            result.put("createTime", System.currentTimeMillis());
            result.put("success", true);

            log.info("对话创建成功: conversationId={}", conversation.getId());

        } catch (Exception e) {
            log.error("创建对话失败", e);
            result.put("success", false);
            result.put("error", "创建对话失败");
        }

        return result;
    }

    /**
     * 构建Coze API请求 - 根据官方文档修正格式
     */
    private Map<String, Object> buildCozeRequest(String conversationId, String userMessage, String userId) {
        // 获取聊天场景的AI配置
        AiConfig config = getChatAiConfig();
        return buildCozeRequestWithConfig(conversationId, userMessage, userId, config);
    }

    /**
     * 使用指定配置构建Coze API请求
     */
    private Map<String, Object> buildCozeRequestWithConfig(String conversationId, String userMessage, String userId, AiConfig config) {
        Map<String, Object> cozeRequest = new HashMap<>();
        
        // 严格按照成功示例的字段顺序和格式构建请求
        cozeRequest.put("bot_id", config.getBotId());
        cozeRequest.put("user_id", userId != null ? userId : DEFAULT_USER_ID);
        
        // 根据配置决定是否使用流式输出
        boolean useStream = config.getSupportStream() != null && config.getSupportStream() == 1;
        cozeRequest.put("stream", useStream);

        // 构建消息列表 - 严格按照成功示例的格式
        java.util.List<Map<String, Object>> messages = new java.util.ArrayList<>();

        // 添加当前用户消息，格式完全按照成功示例
        Map<String, Object> currentMsg = new HashMap<>();
        currentMsg.put("role", "user");
        currentMsg.put("content", userMessage);
        currentMsg.put("content_type", "text");
        currentMsg.put("type", "question"); // 根据成功示例添加type字段
        messages.add(currentMsg);

        cozeRequest.put("additional_messages", messages);
        
        // 添加空的parameters对象（根据成功示例）
        Map<String, Object> parameters = new HashMap<>();
        cozeRequest.put("parameters", parameters);
        
        // 如果有workflow_id，则添加（根据成功示例，这是必需的）
        if (config.getWorkflowId() != null && !config.getWorkflowId().trim().isEmpty()) {
            cozeRequest.put("workflow_id", config.getWorkflowId());
        }

        log.info("构建Coze请求完成: botId={}, workflowId={}, userId={}, stream={}, messageCount={}", 
                config.getBotId(), config.getWorkflowId(), userId, useStream, messages.size());
        
        // 验证请求参数
        validateCozeRequest(cozeRequest);

        return cozeRequest;
    }

    /**
     * 从Coze响应中提取chat_id
     */
    private String extractChatIdFromResponse(JSONObject responseJson) {
        try {
            if (responseJson != null && responseJson.getJSONObject("data") != null) {
                return responseJson.getJSONObject("data").getString("id");
            }
        } catch (Exception e) {
            log.error("提取chat_id失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 从Coze响应中提取conversation_id
     */
    private String extractConversationIdFromResponse(JSONObject responseJson) {
        try {
            if (responseJson != null && responseJson.getJSONObject("data") != null) {
                return responseJson.getJSONObject("data").getString("conversation_id");
            }
        } catch (Exception e) {
            log.error("提取conversation_id失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 等待聊天完成并获取回复内容
     */
    private String waitForChatCompletion(String chatId, String conversationId) {
        try {
            // 获取聊天场景的AI配置
            AiConfig config = getChatAiConfig();
            
            // 最多等待30秒，每2秒轮询一次
            int maxAttempts = 15;
            int attempt = 0;

            while (attempt < maxAttempts) {
                log.info("轮询聊天状态，第{}次尝试: chatId={}, conversationId={}", attempt + 1, chatId, conversationId);

                // 构建状态查询URL（使用基础URL拼接状态查询路径）
                String baseUrl = extractBaseUrl(config.getApiBaseUrl());
                String statusUrl = baseUrl + "/v3/chat/retrieve?chat_id=" + chatId + "&conversation_id="
                        + conversationId;

                // 构建请求头
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", "Bearer " + config.getApiToken());
                headers.set("Content-Type", "application/json");

                HttpEntity<String> request = new HttpEntity<>(headers);

                // 发送状态查询请求
                ResponseEntity<String> response = restTemplate.exchange(
                        statusUrl,
                        HttpMethod.GET,
                        request,
                        String.class);

                JSONObject statusResponse = JSON.parseObject(response.getBody());
                log.info("轮询响应: {}", statusResponse);

                if (statusResponse != null && statusResponse.getJSONObject("data") != null) {
                    JSONObject data = statusResponse.getJSONObject("data");
                    String status = data.getString("status");
                    log.info("聊天状态: {}", status);

                    if ("completed".equals(status)) {
                        // 聊天完成，获取消息
                        log.info("聊天完成，开始获取消息: chatId={}, conversationId={}", chatId, conversationId);
                        return getChatMessages(chatId, conversationId);
                    } else if ("failed".equals(status)) {
                        log.error("Coze聊天失败: chatId={}, conversationId={}", chatId, conversationId);
                        return "抱歉，AI服务暂时不可用，请稍后再试。";
                    }
                } else {
                    log.warn("轮询响应为空或无data字段: {}", statusResponse);
                }

                // 等待2秒后重试
                Thread.sleep(2000);
                attempt++;
            }

            log.warn("Coze聊天超时: chatId={}, conversationId={}", chatId, conversationId);
            return "抱歉，AI响应超时，请稍后再试。";

        } catch (Exception e) {
            log.error("等待Coze聊天完成失败: chatId={}, conversationId={}, error={}",
                    chatId, conversationId, e.getMessage(), e);
            return "抱歉，AI服务出现错误，请稍后再试。";
        }
    }

    /**
     * 获取聊天消息
     */
    private String getChatMessages(String chatId, String conversationId) {
        try {
            // 获取聊天场景的AI配置
            AiConfig config = getChatAiConfig();
            
            log.info("获取聊天消息: chatId={}, conversationId={}", chatId, conversationId);

            // 构建消息查询URL（使用基础URL拼接消息查询路径）
            String baseUrl = extractBaseUrl(config.getApiBaseUrl());
            String messagesUrl = baseUrl + "/v3/chat/message/list?chat_id=" + chatId + "&conversation_id="
                    + conversationId;

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + config.getApiToken());
            headers.set("Content-Type", "application/json");

            HttpEntity<String> request = new HttpEntity<>(headers);

            // 发送消息查询请求
            ResponseEntity<String> response = restTemplate.exchange(
                    messagesUrl,
                    HttpMethod.GET,
                    request,
                    String.class);

            JSONObject messagesResponse = JSON.parseObject(response.getBody());
            log.info("消息响应: {}", messagesResponse);

            if (messagesResponse != null && messagesResponse.getJSONArray("data") != null) {
                java.util.List<JSONObject> messages = messagesResponse.getJSONArray("data")
                        .toJavaList(JSONObject.class);
                log.info("收到{}条消息", messages.size());

                // 查找AI的回复消息（role=assistant, type=answer）
                for (JSONObject message : messages) {
                    String role = message.getString("role");
                    String type = message.getString("type");
                    log.info("消息详情: role={}, type={}, content={}", role, type, message.getString("content"));

                    if (ASSISTANT_ROLE.equals(role) && ANSWER_TYPE.equals(type)) {
                        String content = message.getString("content");
                        log.info("找到AI回复: {}", content);
                        return content;
                    }
                }
                log.warn("未找到AI回复消息");
            } else {
                log.warn("消息响应为空或无data字段");
            }

            return "抱歉，未能获取到AI回复。";

        } catch (Exception e) {
            log.error("获取Coze聊天消息失败: chatId={}, conversationId={}, error={}",
                    chatId, conversationId, e.getMessage(), e);
            return "抱歉，获取AI回复失败。";
        }
    }

    /**
     * 构建总结请求 - 使用专门的总结bot和workflow
     */
    private Map<String, Object> buildSummaryRequest(String conversationId, String userMessage, String userId) {
        // 获取总结场景的AI配置
        AiConfig config = getSummaryAiConfig();
        
        Map<String, Object> cozeRequest = new HashMap<>();
        cozeRequest.put("bot_id", config.getBotId());

        // 如果有workflow_id，则添加
        if (config.getWorkflowId() != null && !config.getWorkflowId().trim().isEmpty()) {
            cozeRequest.put("workflow_id", config.getWorkflowId());
        }

        cozeRequest.put("user_id", userId != null ? userId : DEFAULT_USER_ID);
        
        // 根据配置决定是否使用流式输出
        boolean useStream = config.getSupportStream() != null && config.getSupportStream() == 1;
        cozeRequest.put("stream", useStream);
        cozeRequest.put("auto_save_history", true);

        // 如果有会话ID，则添加
        if (conversationId != null && !conversationId.trim().isEmpty()) {
            cozeRequest.put("conversation_id", conversationId);
        }

        // 构建消息列表 - 按照 Coze API 标准格式
        java.util.List<Map<String, Object>> messages = new java.util.ArrayList<>();

        // 添加当前用户消息
        Map<String, Object> currentMsg = new HashMap<>();
        currentMsg.put(ROLE_KEY, USER_ROLE);
        currentMsg.put(CONTENT_KEY, userMessage);
        currentMsg.put(CONTENT_TYPE_KEY, TEXT_TYPE);
        currentMsg.put("type", "question"); // 添加type字段
        messages.add(currentMsg);

        cozeRequest.put("additional_messages", messages);

        return cozeRequest;
    }

    /**
     * 获取对话历史
     */
    private String getConversationHistory(String conversationId) {
        try {
            // 这里应该从数据库获取对话历史
            // 暂时返回空字符串
            return "";
        } catch (Exception e) {
            log.error("获取对话历史失败", e);
            return "";
        }
    }

    /**
     * 创建API调用记录
     */
    private CozeApiCall createApiCallRecord(String conversationId, String messageId, String userMessage, String userId,
            String requestType) {
        // 获取聊天场景的AI配置
        AiConfig config = getChatAiConfig();
        
        CozeApiCall apiCall = CozeApiCall.builder()
                .conversationId(conversationId)
                .messageId(messageId) // 设置messageId
                .userId(userId)
                .requestType(requestType)
                .userMessage(userMessage)
                .userMessageType("text")
                .botId(config.getBotId())
                .workflowId(config.getWorkflowId())
                .status("pending")
                .startTime(LocalDateTime.now())
                .traceId(UUID.randomUUID().toString())
                .createBy(userId) // 设置创建人为当前用户
                .updateBy(userId) // 设置更新人为当前用户
                .build();

        // 获取客户端信息
        try {
            HttpServletRequest request = getCurrentRequest();
            if (request != null) {
                apiCall.setClientIp(getClientIp(request));
                apiCall.setUserAgent(request.getHeader("User-Agent"));
                apiCall.setSessionId(request.getSession().getId());
            }
        } catch (Exception e) {
            log.warn("获取客户端信息失败: {}", e.getMessage());
        }

        // 保存API调用记录
        cozeApiCallService.save(apiCall);
        log.info("创建API调用记录: id={}, messageId={}, traceId={}", apiCall.getId(), messageId, apiCall.getTraceId());

        return apiCall;
    }

    /**
     * 创建总结API调用记录
     */
    private CozeApiCall createSummaryApiCallRecord(String conversationId, String messageId, String userMessage,
            String userId, String requestType) {
        // 获取总结场景的AI配置
        AiConfig config = getSummaryAiConfig();
        
        CozeApiCall apiCall = CozeApiCall.builder()
                .conversationId(conversationId)
                .messageId(messageId) // 设置messageId
                .userId(userId)
                .requestType(requestType)
                .userMessage(userMessage)
                .userMessageType("text")
                .botId(config.getBotId())
                .workflowId(config.getWorkflowId())
                .status("pending")
                .startTime(LocalDateTime.now())
                .traceId(UUID.randomUUID().toString())
                .createBy(userId) // 设置创建人为当前用户
                .updateBy(userId) // 设置更新人为当前用户
                .build();

        // 获取客户端信息
        try {
            HttpServletRequest request = getCurrentRequest();
            if (request != null) {
                apiCall.setClientIp(getClientIp(request));
                apiCall.setUserAgent(request.getHeader("User-Agent"));
                apiCall.setSessionId(request.getSession().getId());
            }
        } catch (Exception e) {
            log.warn("获取客户端信息失败: {}", e.getMessage());
        }

        // 保存API调用记录
        cozeApiCallService.save(apiCall);
        log.info("创建总结API调用记录: id={}, messageId={}, traceId={}", apiCall.getId(), messageId, apiCall.getTraceId());

        return apiCall;
    }

    /**
     * 更新API调用记录的请求信息
     */
    private void updateApiCallRequest(CozeApiCall apiCall, String requestUrl, Map<String, Object> requestBody,
            HttpHeaders headers) {
        try {
            apiCall.setRequestUrl(requestUrl);
            apiCall.setRequestBody(JSON.toJSONString(requestBody));
            apiCall.setRequestHeaders(JSON.toJSONString(headers.toSingleValueMap()));
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("更新API调用记录请求信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新API调用记录的响应信息
     */
    private void updateApiCallResponse(CozeApiCall apiCall, ResponseEntity<String> response) {
        try {
            apiCall.setResponseStatus(response.getStatusCodeValue());
            
            // 确保响应体是有效的JSON格式
            String responseBody = response.getBody();
            if (responseBody != null && !responseBody.trim().isEmpty()) {
                try {
                    // 尝试解析为JSON，如果失败则包装成JSON
                    JSON.parseObject(responseBody);
                    apiCall.setResponseBody(responseBody);
                } catch (Exception jsonException) {
                    // 如果不是有效JSON，则包装成JSON格式
                    Map<String, Object> wrapper = new HashMap<>();
                    wrapper.put("type", "raw_response");
                    wrapper.put("data", responseBody);
                    wrapper.put("timestamp", System.currentTimeMillis());
                    apiCall.setResponseBody(JSON.toJSONString(wrapper));
                }
            } else {
                // 空响应体，设置为空JSON对象
                apiCall.setResponseBody("{}");
            }
            
            apiCall.setResponseHeaders(JSON.toJSONString(response.getHeaders().toSingleValueMap()));
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("更新API调用记录响应信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新API调用记录的Coze ID信息
     */
    private void updateApiCallCozeIds(CozeApiCall apiCall, String cozeChatId, String cozeConversationId) {
        try {
            apiCall.setCozeChatId(cozeChatId);
            apiCall.setCozeConversationId(cozeConversationId);
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("更新API调用记录Coze ID信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新API调用记录的成功结果
     */
    private void updateApiCallSuccess(CozeApiCall apiCall, String aiReply) {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            long durationMs = java.time.Duration.between(apiCall.getStartTime(), endTime).toMillis();

            apiCall.setAiReply(aiReply);
            apiCall.setAiReplyType("text");
            apiCall.setStatus("success");
            apiCall.setFinalStatus("completed");
            apiCall.setEndTime(endTime);
            apiCall.setDurationMs((int) durationMs);
            apiCall.setUpdateBy(apiCall.getUserId()); // 设置更新人

            cozeApiCallService.updateById(apiCall);
            log.info("API调用成功: id={}, duration={}ms", apiCall.getId(), durationMs);
        } catch (Exception e) {
            log.error("更新API调用记录成功结果失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新API调用记录的失败结果
     */
    private void updateApiCallFailure(CozeApiCall apiCall, String errorMessage) {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            long durationMs = java.time.Duration.between(apiCall.getStartTime(), endTime).toMillis();

            apiCall.setStatus("failed");
            apiCall.setFinalStatus("failed");
            apiCall.setEndTime(endTime);
            apiCall.setDurationMs((int) durationMs);
            apiCall.setErrorMessage(errorMessage);
            apiCall.setUpdateBy(apiCall.getUserId()); // 设置更新人

            cozeApiCallService.updateById(apiCall);
            log.info("API调用失败: id={}, duration={}ms, error={}", apiCall.getId(), durationMs, errorMessage);
        } catch (Exception e) {
            log.error("更新API调用记录失败结果失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新API调用记录的错误信息
     */
    private void updateApiCallError(CozeApiCall apiCall, String errorCode, String errorMessage) {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            long durationMs = java.time.Duration.between(apiCall.getStartTime(), endTime).toMillis();

            apiCall.setErrorCode(errorCode);
            apiCall.setErrorMessage(errorMessage);
            apiCall.setStatus("failed");
            apiCall.setFinalStatus("failed");
            apiCall.setEndTime(endTime);
            apiCall.setDurationMs((int) durationMs);

            cozeApiCallService.updateById(apiCall);
            log.error("API调用失败: id={}, errorCode={}, errorMessage={}", apiCall.getId(), errorCode, errorMessage);
        } catch (Exception e) {
            log.error("更新API调用记录错误信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 获取当前HTTP请求
     */
    private HttpServletRequest getCurrentRequest() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
            return attributes != null ? attributes.getRequest() : null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        return UserContextUtils.getClientIpAddress(request);
    }

    /**
     * 带跟踪的轮询聊天完成状态
     */
    private String waitForChatCompletionWithTracking(String chatId, String cozeConversationId, CozeApiCall apiCall) {
        try {
            // 更新轮询开始时间
            apiCall.setPollStartTime(LocalDateTime.now());
            apiCall.setPollCount(0);
            cozeApiCallService.updateById(apiCall);

            // 调用原有的轮询方法
            String result = waitForChatCompletion(chatId, cozeConversationId);

            // 更新轮询结束时间
            apiCall.setPollEndTime(LocalDateTime.now());
            cozeApiCallService.updateById(apiCall);

            return result;
        } catch (Exception e) {
            log.error("轮询聊天完成状态失败", e);
            throw e;
        }
    }

    /**
     * 整合聊天记录
     */
    private String integrateChatHistory(List<Message> messages) {
        StringBuilder chatHistory = new StringBuilder();
        chatHistory.append("以下是用户今天的聊天记录：\n\n");

        for (Message message : messages) {
            String sender = "ai".equals(message.getSender()) ? "AI助手" : "用户";
            String timestamp = message.getCreateTime().format(DateTimeFormatter.ofPattern("HH:mm"));
            chatHistory.append(String.format("[%s] %s: %s\n", timestamp, sender, message.getContent()));
        }

        return chatHistory.toString();
    }

    /**
     * 构建情绪分析提示词
     */
    private String buildEmotionAnalysisPrompt(String chatHistory) {
        return String.format("""
                请分析以下聊天记录中用户的情绪状态，并生成一个情绪总结报告。

                %s

                请从以下几个维度进行分析：
                1. 主要情绪类型（如：开心、焦虑、愤怒、悲伤、平静等）
                2. 情绪强度（0-1之间的数值，0表示很轻微，1表示很强烈）
                3. 情绪触发因素（导致情绪变化的主要原因）
                4. 情绪变化趋势（情绪在对话过程中的变化）
                5. 建议和关怀（针对用户情绪状态的建议）

                请以JSON格式返回分析结果：
                {
                    "primaryEmotion": "主要情绪类型",
                    "intensity": 0.8,
                    "triggers": "触发因素描述",
                    "emotionTrend": "情绪变化趋势",
                    "suggestions": "建议和关怀",
                    "summary": "整体情绪总结"
                }
                """, chatHistory);
    }

    /**
     * 解析情绪分析总结结果
     */
    private EmotionAnalysis parseEmotionSummary(String summary) {
        try {
            // 尝试从AI回复中提取JSON
            String jsonStr = extractJsonFromSummary(summary);
            if (jsonStr != null) {
                JSONObject json = JSON.parseObject(jsonStr);

                return EmotionAnalysis.builder()
                        .primaryEmotion(json.getString("primaryEmotion"))
                        .intensity(BigDecimal.valueOf(json.getDoubleValue("intensity")))
                        .keywords(JSON.toJSONString(Arrays.asList(json.getString("triggers"))))
                        .suggestion(json.getString("suggestions"))
                        .text(summary)
                        .polarity(determinePolarity(json.getString("primaryEmotion")))
                        .confidence(BigDecimal.valueOf(0.85))
                        .analysisTime(LocalDateTime.now())
                        .build();
            }
        } catch (Exception e) {
            log.warn("解析情绪分析结果失败，使用默认值: {}", e.getMessage());
        }

        // 如果解析失败，返回默认结果
        return EmotionAnalysis.builder()
                .primaryEmotion("平静")
                .intensity(BigDecimal.valueOf(0.5))
                .keywords(JSON.toJSONString(Arrays.asList("日常对话")))
                .suggestion("保持当前的积极状态")
                .text(summary)
                .polarity("neutral")
                .confidence(BigDecimal.valueOf(0.5))
                .analysisTime(LocalDateTime.now())
                .build();
    }

    /**
     * 根据主要情绪确定情绪极性
     */
    private String determinePolarity(String primaryEmotion) {
        if (primaryEmotion == null || primaryEmotion.trim().isEmpty()) {
            return "neutral";
        }

        String emotion = primaryEmotion.toLowerCase().trim();

        // 积极情绪
        if (emotion.contains("快乐") || emotion.contains("高兴") || emotion.contains("喜悦") ||
                emotion.contains("兴奋") || emotion.contains("满足") || emotion.contains("感激") ||
                emotion.contains("爱") || emotion.contains("希望") || emotion.contains("自信") ||
                emotion.contains("平静") || emotion.contains("放松") || emotion.contains("开心") ||
                emotion.contains("幸福") || emotion.contains("乐观") || emotion.contains("满意")) {
            return "positive";
        }

        // 消极情绪
        if (emotion.contains("悲伤") || emotion.contains("愤怒") || emotion.contains("恐惧") ||
                emotion.contains("焦虑") || emotion.contains("沮丧") || emotion.contains("失望") ||
                emotion.contains("孤独") || emotion.contains("痛苦") || emotion.contains("绝望") ||
                emotion.contains("愧疚") || emotion.contains("羞耻") || emotion.contains("嫉妒") ||
                emotion.contains("厌恶") || emotion.contains("烦躁") || emotion.contains("压抑") ||
                emotion.contains("无助") || emotion.contains("困惑") || emotion.contains("担心")) {
            return "negative";
        }

        // 默认为中性
        return "neutral";
    }

    /**
     * 从AI回复中提取JSON字符串
     */
    private String extractJsonFromSummary(String summary) {
        try {
            int startIndex = summary.indexOf("{");
            int endIndex = summary.lastIndexOf("}");
            if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
                return summary.substring(startIndex, endIndex + 1);
            }
        } catch (Exception e) {
            log.warn("提取JSON失败: {}", e.getMessage());
        }
        return null;
    }

    /**
     * 创建情绪记录
     */
    private EmotionRecord createEmotionRecord(String userId, EmotionAnalysis analysisResult, String chatHistory) {
        EmotionRecord record = EmotionRecord.builder()
                .userId(userId)
                .recordDate(LocalDate.now())
                .emotionType(analysisResult.getPrimaryEmotion())
                .intensity(analysisResult.getIntensity())
                .triggers(analysisResult.getKeywords())
                .description(analysisResult.getText())
                .notes("基于当天聊天记录自动生成的情绪分析")
                .tags(JSON.toJSONString(Arrays.asList("AI分析", "聊天记录", "情绪总结")))
                .build();

        emotionRecordService.save(record);
        log.info("情绪记录创建成功: recordId={}", record.getId());

        // 设置情绪分析记录的关联ID并保存
        analysisResult.setUserId(userId);
        analysisResult.setMessageId(record.getId()); // 关联到情绪记录ID

        emotionAnalysisService.save(analysisResult);
        log.info("情绪分析记录创建成功: analysisId={}", analysisResult.getId());

        return record;
    }

    /**
     * 获取聊天场景的AI配置
     */
    private AiConfig getChatAiConfig() {
        AiConfig config = aiConfigService.getBestConfig(USAGE_SCENARIO_CHAT, DEFAULT_ENVIRONMENT);
        if (config == null) {
            log.error("未找到聊天场景的AI配置");
            throw new RuntimeException("未找到聊天场景的AI配置，请先在管理后台配置");
        }
        return config;
    }

    /**
     * 获取总结场景的AI配置
     */
    private AiConfig getSummaryAiConfig() {
        AiConfig config = aiConfigService.getBestConfig(USAGE_SCENARIO_SUMMARY, DEFAULT_ENVIRONMENT);
        if (config == null) {
            log.warn("未找到总结场景的AI配置，使用聊天配置");
            return getChatAiConfig();
        }
        return config;
    }

    /**
     * 获取配置的API路径
     * apiBaseUrl已经是完整的API URL，不需要再拼接路径
     */
    private String getApiPath(AiConfig config) {
        // apiBaseUrl已经是完整的URL，返回空字符串
        return "";
    }
    
    /**
     * 从apiBaseUrl中提取基础URL（用于状态查询和消息查询等辅助接口）
     * 例如：https://api.coze.cn/v3/chat -> https://api.coze.cn
     */
    private String extractBaseUrl(String apiBaseUrl) {
        if (apiBaseUrl == null || apiBaseUrl.isEmpty()) {
            return "";
        }
        try {
            java.net.URL url = new java.net.URL(apiBaseUrl);
            return url.getProtocol() + "://" + url.getHost() + (url.getPort() > 0 ? ":" + url.getPort() : "");
        } catch (Exception e) {
            log.warn("解析apiBaseUrl失败: {}", apiBaseUrl, e);
            // 尝试简单截取
            int pathIndex = apiBaseUrl.indexOf("/", apiBaseUrl.indexOf("://") + 3);
            if (pathIndex > 0) {
                return apiBaseUrl.substring(0, pathIndex);
            }
            return apiBaseUrl;
        }
    }

    /**
     * 从content字段中提取output内容
     */
    private String extractOutputFromContent(String content) {
        try {
            // 尝试解析content为JSON
            JSONObject contentJson = JSON.parseObject(content);
            if (contentJson.containsKey("output")) {
                String output = contentJson.getString("output");
                log.debug("成功提取output内容: {}", output);
                return output;
            } else {
                log.debug("content中没有output字段，返回原始内容: {}", content);
                return content;
            }
        } catch (Exception e) {
            log.debug("content不是有效JSON，返回原始内容: {}, 错误: {}", content, e.getMessage());
            return content;
        }
    }

    /**
     * 验证Coze请求参数
     */
    private void validateCozeRequest(Map<String, Object> cozeRequest) {
        log.debug("验证Coze请求参数: {}", JSON.toJSONString(cozeRequest));
        
        // 检查必需参数
        if (!cozeRequest.containsKey("bot_id") || cozeRequest.get("bot_id") == null) {
            throw new RuntimeException("缺少必需参数: bot_id");
        }
        
        if (!cozeRequest.containsKey("user_id") || cozeRequest.get("user_id") == null) {
            throw new RuntimeException("缺少必需参数: user_id");
        }
        
        if (!cozeRequest.containsKey("additional_messages") || cozeRequest.get("additional_messages") == null) {
            throw new RuntimeException("缺少必需参数: additional_messages");
        }
        
        // 检查消息格式
        @SuppressWarnings("unchecked")
        java.util.List<Map<String, Object>> messages = (java.util.List<Map<String, Object>>) cozeRequest.get("additional_messages");
        if (messages.isEmpty()) {
            throw new RuntimeException("additional_messages不能为空");
        }
        
        for (Map<String, Object> message : messages) {
            if (!message.containsKey("role") || message.get("role") == null) {
                throw new RuntimeException("消息缺少必需参数: role");
            }
            if (!message.containsKey("content") || message.get("content") == null) {
                throw new RuntimeException("消息缺少必需参数: content");
            }
            if (!message.containsKey("content_type") || message.get("content_type") == null) {
                throw new RuntimeException("消息缺少必需参数: content_type");
            }
            if (!message.containsKey("type") || message.get("type") == null) {
                throw new RuntimeException("消息缺少必需参数: type");
            }
        }
        
        log.debug("Coze请求参数验证通过");
    }

    // ==================== 通用工作流调用方法 ====================

    @Override
    public String callWorkflowByConfigKey(String configKey, String input, String userId) {
        log.info("通过配置键调用Coze工作流: configKey={}, userId={}", configKey, userId);
        
        // 构建参数Map
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("input", input);
        parameters.put("user_id", userId);
        
        return callWorkflowByConfigKey(configKey, parameters, userId);
    }

    @Override
    public String callWorkflowByConfigKey(String configKey, Map<String, Object> parameters, String userId) {
        log.info("通过配置键调用Coze工作流（带参数）: configKey={}, userId={}", configKey, userId);
        
        // 1. 获取AI配置
        AiConfig config = aiConfigService.getByConfigKey(configKey);
        if (config == null) {
            log.error("未找到AI配置或配置已禁用: configKey={}", configKey);
            throw new RuntimeException("未找到AI配置: " + configKey);
        }
        
        // 2. 构建工作流请求
        Map<String, Object> requestBody = buildWorkflowRequest(config, parameters, userId);
        
        // 3. 创建API调用记录
        String userInput = parameters != null ? String.valueOf(parameters.get("input")) : "";
        CozeApiCall apiCall = createWorkflowApiCallRecord(config, configKey, userInput, userId);
        
        // 4. 执行工作流调用
        return executeWorkflowCallWithRecord(config, requestBody, configKey, userId, apiCall);
    }

    /**
     * 构建Coze工作流请求体
     * 
     * @param config AI配置
     * @param parameters 运行时参数
     * @param userId 用户ID
     * @return 请求体Map
     */
    private Map<String, Object> buildWorkflowRequest(AiConfig config, Map<String, Object> parameters, String userId) {
        Map<String, Object> requestBody = new HashMap<>();
        
        // 设置workflow_id
        if (config.getWorkflowId() != null && !config.getWorkflowId().trim().isEmpty()) {
            requestBody.put("workflow_id", config.getWorkflowId());
        }
        
        // 设置user_id
        requestBody.put("user_id", userId != null ? userId : DEFAULT_USER_ID);
        
        // 设置stream为true（默认流式调用）
        requestBody.put("stream", true);
        
        // 合并custom_params和运行时参数
        Map<String, Object> mergedParameters = mergeParameters(config, parameters);
        requestBody.put("parameters", mergedParameters);
        
        log.info("构建工作流请求完成: workflowId={}, userId={}, parametersKeys={}", 
                config.getWorkflowId(), userId, mergedParameters.keySet());
        
        return requestBody;
    }

    /**
     * 合并配置中的custom_params和运行时参数
     * 运行时参数优先级高于custom_params
     * 
     * @param config AI配置
     * @param runtimeParameters 运行时参数
     * @return 合并后的参数Map
     */
    private Map<String, Object> mergeParameters(AiConfig config, Map<String, Object> runtimeParameters) {
        Map<String, Object> mergedParams = new HashMap<>();
        
        // 1. 先加载custom_params中的parameters
        if (config.getCustomParams() != null && !config.getCustomParams().trim().isEmpty()) {
            try {
                JSONObject customParamsJson = JSON.parseObject(config.getCustomParams());
                if (customParamsJson.containsKey("parameters")) {
                    JSONObject configParams = customParamsJson.getJSONObject("parameters");
                    if (configParams != null) {
                        mergedParams.putAll(configParams);
                    }
                }
            } catch (Exception e) {
                log.warn("解析custom_params失败: {}", e.getMessage());
            }
        }
        
        // 2. 运行时参数覆盖配置参数
        if (runtimeParameters != null) {
            mergedParams.putAll(runtimeParameters);
        }
        
        return mergedParams;
    }

    /**
     * 执行Coze工作流调用（带重试机制）
     * 
     * @param config AI配置
     * @param requestBody 请求体
     * @param configKey 配置键（用于日志）
     * @param userId 用户ID
     * @return AI生成的内容
     */
    private String executeWorkflowCall(AiConfig config, Map<String, Object> requestBody, String configKey, String userId) {
        // 获取重试配置
        int maxRetries = config.getRetryCount() != null ? config.getRetryCount() : 0;
        int retryDelayMs = config.getRetryDelayMs() != null ? config.getRetryDelayMs() : 1000;
        
        Exception lastException = null;
        
        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                if (attempt > 0) {
                    log.info("Coze工作流调用重试: configKey={}, 第{}次重试", configKey, attempt);
                    Thread.sleep(retryDelayMs);
                }
                
                return doExecuteWorkflowCall(config, requestBody, configKey);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("Coze工作流调用被中断: configKey={}", configKey);
                throw new RuntimeException("AI服务调用被中断");
            } catch (Exception e) {
                lastException = e;
                log.warn("Coze工作流调用失败: configKey={}, 尝试次数={}/{}, error={}", 
                        configKey, attempt + 1, maxRetries + 1, e.getMessage());
                
                if (attempt >= maxRetries) {
                    break;
                }
            }
        }
        
        log.error("Coze工作流调用最终失败: configKey={}, 已重试{}次, error={}", 
                configKey, maxRetries, lastException != null ? lastException.getMessage() : "未知错误");
        throw new RuntimeException("AI服务调用失败: " + (lastException != null ? lastException.getMessage() : "未知错误"));
    }

    /**
     * 执行Coze工作流调用（带重试机制和API调用记录）
     * 
     * @param config AI配置
     * @param requestBody 请求体
     * @param configKey 配置键（用于日志）
     * @param userId 用户ID
     * @param apiCall API调用记录
     * @return AI生成的内容
     */
    private String executeWorkflowCallWithRecord(AiConfig config, Map<String, Object> requestBody, 
            String configKey, String userId, CozeApiCall apiCall) {
        // 获取重试配置
        int maxRetries = config.getRetryCount() != null ? config.getRetryCount() : 0;
        int retryDelayMs = config.getRetryDelayMs() != null ? config.getRetryDelayMs() : 1000;
        
        Exception lastException = null;
        
        for (int attempt = 0; attempt <= maxRetries; attempt++) {
            try {
                if (attempt > 0) {
                    log.info("Coze工作流调用重试: configKey={}, 第{}次重试", configKey, attempt);
                    Thread.sleep(retryDelayMs);
                }
                
                return doExecuteWorkflowCallWithRecord(config, requestBody, configKey, apiCall);
                
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("Coze工作流调用被中断: configKey={}", configKey);
                updateWorkflowApiCallError(apiCall, "INTERRUPTED", "AI服务调用被中断");
                throw new RuntimeException("AI服务调用被中断");
            } catch (Exception e) {
                lastException = e;
                log.warn("Coze工作流调用失败: configKey={}, 尝试次数={}/{}, error={}", 
                        configKey, attempt + 1, maxRetries + 1, e.getMessage());
                
                if (attempt >= maxRetries) {
                    break;
                }
            }
        }
        
        log.error("Coze工作流调用最终失败: configKey={}, 已重试{}次, error={}", 
                configKey, maxRetries, lastException != null ? lastException.getMessage() : "未知错误");
        updateWorkflowApiCallError(apiCall, "MAX_RETRY_EXCEEDED", 
                lastException != null ? lastException.getMessage() : "未知错误");
        throw new RuntimeException("AI服务调用失败: " + (lastException != null ? lastException.getMessage() : "未知错误"));
    }

    /**
     * 执行单次Coze工作流调用
     * 
     * @param config AI配置
     * @param requestBody 请求体
     * @param configKey 配置键（用于日志）
     * @return AI生成的内容
     */
    private String doExecuteWorkflowCall(AiConfig config, Map<String, Object> requestBody, String configKey) {
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiToken());
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "text/event-stream");
        
        String apiUrl = config.getApiBaseUrl();
        
        log.info("发送Coze工作流请求: configKey={}, url={}", configKey, apiUrl);
        log.debug("请求体: {}", JSON.toJSONString(requestBody));
        
        // 执行流式调用
        String result = handleWorkflowStreamResponse(apiUrl, headers, requestBody, config);
        
        log.info("Coze工作流调用成功: configKey={}, resultLength={}", configKey, result != null ? result.length() : 0);
        
        return result;
    }

    /**
     * 执行单次Coze工作流调用（带API调用记录）
     * 
     * @param config AI配置
     * @param requestBody 请求体
     * @param configKey 配置键（用于日志）
     * @param apiCall API调用记录
     * @return AI生成的内容
     */
    private String doExecuteWorkflowCallWithRecord(AiConfig config, Map<String, Object> requestBody, 
            String configKey, CozeApiCall apiCall) {
        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + config.getApiToken());
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "text/event-stream");
        
        String apiUrl = config.getApiBaseUrl();
        
        // 更新API调用记录的请求信息
        updateWorkflowApiCallRequest(apiCall, apiUrl, requestBody, headers);
        
        log.info("发送Coze工作流请求: configKey={}, url={}, apiCallId={}", configKey, apiUrl, apiCall.getId());
        log.debug("请求体: {}", JSON.toJSONString(requestBody));
        
        // 执行流式调用
        String result = handleWorkflowStreamResponseWithRecord(apiUrl, headers, requestBody, config, apiCall);
        
        // 更新API调用记录的成功结果
        updateWorkflowApiCallSuccess(apiCall, result);
        
        log.info("Coze工作流调用成功: configKey={}, resultLength={}, apiCallId={}", 
                configKey, result != null ? result.length() : 0, apiCall.getId());
        
        return result;
    }

    /**
     * 处理Coze工作流流式响应
     * 
     * @param url API URL
     * @param headers 请求头
     * @param requestBody 请求体
     * @param config AI配置
     * @return 提取的output内容
     */
    private String handleWorkflowStreamResponse(String url, HttpHeaders headers, Map<String, Object> requestBody, AiConfig config) {
        try {
            log.info("开始处理工作流流式响应，URL: {}", url);
            
            // 获取超时配置
            int timeoutMs = config.getTimeoutMs() != null ? config.getTimeoutMs() : 30000;
            
            // 创建HTTP客户端
            java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
                    .connectTimeout(java.time.Duration.ofMillis(timeoutMs))
                    .build();

            // 构建请求
            java.net.http.HttpRequest.Builder requestBuilder = java.net.http.HttpRequest.newBuilder()
                    .uri(java.net.URI.create(url))
                    .timeout(java.time.Duration.ofMillis(timeoutMs * 2))
                    .POST(java.net.http.HttpRequest.BodyPublishers.ofString(JSON.toJSONString(requestBody)));

            // 添加请求头
            headers.forEach((key, values) -> {
                if (values != null && !values.isEmpty()) {
                    requestBuilder.header(key, values.get(0));
                }
            });

            java.net.http.HttpRequest request = requestBuilder.build();

            // 发送请求并处理流式响应
            java.net.http.HttpResponse<java.util.stream.Stream<String>> response = client.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofLines());

            log.info("工作流流式响应状态码: {}", response.statusCode());

            if (response.statusCode() != 200) {
                String errorBody = response.body().collect(java.util.stream.Collectors.joining("\n"));
                log.error("工作流请求失败，状态码: {}, 响应: {}", response.statusCode(), errorBody);
                throw new RuntimeException("工作流请求失败，状态码: " + response.statusCode());
            }

            // 解析SSE流式响应
            return parseWorkflowSseResponse(response.body());

        } catch (Exception e) {
            log.error("处理工作流流式响应失败: {}", e.getMessage(), e);
            throw new RuntimeException("处理工作流响应失败: " + e.getMessage());
        }
    }

    /**
     * 解析Coze工作流SSE响应
     * 格式：
     * id: 0
     * event: Message
     * data: {"node_title":"End",...,"content":"{\"output\":\"...\"}","node_type":"End",...}
     * 
     * id: 1
     * event: Done
     * data: {...}
     * 
     * @param lines 响应行流
     * @return 提取的output内容
     */
    private String parseWorkflowSseResponse(java.util.stream.Stream<String> lines) {
        StringBuilder resultBuilder = new StringBuilder();
        StringBuilder fullStreamData = new StringBuilder();
        String currentEvent = null;
        
        java.util.Iterator<String> lineIterator = lines.iterator();
        while (lineIterator.hasNext()) {
            String line = lineIterator.next();
            fullStreamData.append(line).append("\n");
            
            if (line.trim().isEmpty()) {
                currentEvent = null;
                continue;
            }
            
            // 解析event行
            if (line.startsWith("event:")) {
                currentEvent = line.substring(6).trim();
                log.debug("工作流事件类型: {}", currentEvent);
                continue;
            }
            
            // 解析data行
            if (line.startsWith("data:")) {
                String data = line.substring(5).trim();
                
                // 检查是否为结束标记
                if ("\"[DONE]\"".equals(data) || "[DONE]".equals(data)) {
                    log.info("收到工作流响应结束标记");
                    break;
                }
                
                if (data.isEmpty()) {
                    continue;
                }
                
                // 处理Message事件
                if ("Message".equals(currentEvent)) {
                    try {
                        JSONObject jsonData = JSON.parseObject(data);
                        String nodeType = jsonData.getString("node_type");
                        
                        // 只处理End节点的内容
                        if ("End".equals(nodeType)) {
                            String content = jsonData.getString("content");
                            if (content != null && !content.trim().isEmpty()) {
                                // 从content中提取output
                                String output = extractOutputFromContent(content);
                                if (output != null) {
                                    resultBuilder.append(output);
                                    log.info("成功提取工作流output内容，长度: {}", output.length());
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.warn("解析工作流Message数据失败: {}, 数据: {}", e.getMessage(), data);
                    }
                }
                // 处理Done事件
                else if ("Done".equals(currentEvent)) {
                    log.info("工作流执行完成");
                    break;
                }
            }
        }
        
        String result = resultBuilder.toString();
        if (result.isEmpty()) {
            log.warn("工作流响应解析完成但内容为空，原始数据: {}", fullStreamData);
            throw new RuntimeException("AI响应解析失败：未能提取到有效内容");
        }
        
        return result;
    }

    // ==================== 工作流API调用记录相关方法 ====================

    /**
     * 创建工作流API调用记录
     * 
     * @param config AI配置
     * @param configKey 配置键
     * @param userInput 用户输入
     * @param userId 用户ID
     * @return API调用记录
     */
    private CozeApiCall createWorkflowApiCallRecord(AiConfig config, String configKey, String userInput, String userId) {
        CozeApiCall apiCall = CozeApiCall.builder()
                .id(snowflakeIdGenerator.nextIdAsString())
                .workflowId(config.getWorkflowId())
                .botId(config.getBotId())
                .userId(userId)
                .requestType("workflow")
                .userMessage(userInput)
                .userMessageType("text")
                .status("pending")
                .startTime(LocalDateTime.now())
                .traceId(java.util.UUID.randomUUID().toString().replace("-", ""))
                .metadata(JSON.toJSONString(java.util.Map.of("configKey", configKey)))
                .createBy(userId)
                .build();
        
        // 保存API调用记录
        cozeApiCallService.save(apiCall);
        log.info("创建工作流API调用记录: id={}, workflowId={}, configKey={}, traceId={}", 
                apiCall.getId(), config.getWorkflowId(), configKey, apiCall.getTraceId());
        
        return apiCall;
    }

    /**
     * 更新工作流API调用记录的请求信息
     * 
     * @param apiCall API调用记录
     * @param requestUrl 请求URL
     * @param requestBody 请求体
     * @param headers 请求头
     */
    private void updateWorkflowApiCallRequest(CozeApiCall apiCall, String requestUrl, 
            Map<String, Object> requestBody, HttpHeaders headers) {
        try {
            apiCall.setRequestUrl(requestUrl);
            apiCall.setRequestBody(JSON.toJSONString(requestBody));
            // 脱敏处理请求头，移除Authorization中的token
            Map<String, String> safeHeaders = new HashMap<>();
            headers.toSingleValueMap().forEach((key, value) -> {
                if ("Authorization".equalsIgnoreCase(key)) {
                    safeHeaders.put(key, "Bearer ***");
                } else {
                    safeHeaders.put(key, value);
                }
            });
            apiCall.setRequestHeaders(JSON.toJSONString(safeHeaders));
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("更新工作流API调用记录请求信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新工作流API调用记录的成功结果
     * 
     * @param apiCall API调用记录
     * @param aiReply AI回复内容
     */
    private void updateWorkflowApiCallSuccess(CozeApiCall apiCall, String aiReply) {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            long durationMs = java.time.Duration.between(apiCall.getStartTime(), endTime).toMillis();
            
            apiCall.setEndTime(endTime);
            apiCall.setDurationMs((int) durationMs);
            apiCall.setAiReply(aiReply);
            apiCall.setAiReplyType("text");
            apiCall.setStatus("success");
            apiCall.setFinalStatus("completed");
            apiCall.setResponseStatus(200);
            apiCall.setUpdateBy(apiCall.getUserId());
            
            cozeApiCallService.updateById(apiCall);
            log.info("工作流API调用成功: id={}, duration={}ms, replyLength={}", 
                    apiCall.getId(), durationMs, aiReply != null ? aiReply.length() : 0);
        } catch (Exception e) {
            log.error("更新工作流API调用记录成功结果失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 更新工作流API调用记录的错误信息
     * 
     * @param apiCall API调用记录
     * @param errorCode 错误代码
     * @param errorMessage 错误信息
     */
    private void updateWorkflowApiCallError(CozeApiCall apiCall, String errorCode, String errorMessage) {
        try {
            LocalDateTime endTime = LocalDateTime.now();
            long durationMs = java.time.Duration.between(apiCall.getStartTime(), endTime).toMillis();
            
            apiCall.setEndTime(endTime);
            apiCall.setDurationMs((int) durationMs);
            apiCall.setStatus("failed");
            apiCall.setFinalStatus("failed");
            apiCall.setErrorCode(errorCode);
            apiCall.setErrorMessage(errorMessage);
            apiCall.setUpdateBy(apiCall.getUserId());
            
            cozeApiCallService.updateById(apiCall);
            log.error("工作流API调用失败: id={}, errorCode={}, errorMessage={}", 
                    apiCall.getId(), errorCode, errorMessage);
        } catch (Exception e) {
            log.error("更新工作流API调用记录错误信息失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 处理Coze工作流流式响应（带API调用记录）
     * 
     * @param url API URL
     * @param headers 请求头
     * @param requestBody 请求体
     * @param config AI配置
     * @param apiCall API调用记录
     * @return 提取的output内容
     */
    private String handleWorkflowStreamResponseWithRecord(String url, HttpHeaders headers, 
            Map<String, Object> requestBody, AiConfig config, CozeApiCall apiCall) {
        try {
            log.info("开始处理工作流流式响应，URL: {}, apiCallId: {}", url, apiCall.getId());
            
            // 获取超时配置
            int timeoutMs = config.getTimeoutMs() != null ? config.getTimeoutMs() : 30000;
            
            // 创建HTTP客户端
            java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()
                    .connectTimeout(java.time.Duration.ofMillis(timeoutMs))
                    .build();

            // 构建请求
            java.net.http.HttpRequest.Builder requestBuilder = java.net.http.HttpRequest.newBuilder()
                    .uri(java.net.URI.create(url))
                    .timeout(java.time.Duration.ofMillis(timeoutMs * 2))
                    .POST(java.net.http.HttpRequest.BodyPublishers.ofString(JSON.toJSONString(requestBody)));

            // 添加请求头
            headers.forEach((key, values) -> {
                if (values != null && !values.isEmpty()) {
                    requestBuilder.header(key, values.get(0));
                }
            });

            java.net.http.HttpRequest request = requestBuilder.build();

            // 发送请求并处理流式响应
            java.net.http.HttpResponse<java.util.stream.Stream<String>> response = client.send(request,
                    java.net.http.HttpResponse.BodyHandlers.ofLines());

            log.info("工作流流式响应状态码: {}", response.statusCode());
            
            // 更新响应状态码
            apiCall.setResponseStatus(response.statusCode());

            if (response.statusCode() != 200) {
                String errorBody = response.body().collect(java.util.stream.Collectors.joining("\n"));
                log.error("工作流请求失败，状态码: {}, 响应: {}", response.statusCode(), errorBody);
                // 将错误响应包装成JSON格式存储
                Map<String, Object> errorWrapper = new HashMap<>();
                errorWrapper.put("type", "error");
                errorWrapper.put("data", errorBody);
                errorWrapper.put("timestamp", System.currentTimeMillis());
                apiCall.setResponseBody(JSON.toJSONString(errorWrapper));
                cozeApiCallService.updateById(apiCall);
                throw new RuntimeException("工作流请求失败，状态码: " + response.statusCode());
            }

            // 解析SSE流式响应并记录原始响应
            return parseWorkflowSseResponseWithRecord(response.body(), apiCall);

        } catch (Exception e) {
            log.error("处理工作流流式响应失败: {}", e.getMessage(), e);
            updateWorkflowApiCallError(apiCall, "STREAM_ERROR", e.getMessage());
            throw new RuntimeException("处理工作流响应失败: " + e.getMessage());
        }
    }

    /**
     * 解析Coze工作流SSE响应（带API调用记录）
     * 
     * @param lines 响应行流
     * @param apiCall API调用记录
     * @return 提取的output内容
     */
    private String parseWorkflowSseResponseWithRecord(java.util.stream.Stream<String> lines, CozeApiCall apiCall) {
        StringBuilder resultBuilder = new StringBuilder();
        StringBuilder fullStreamData = new StringBuilder();
        String currentEvent = null;
        
        java.util.Iterator<String> lineIterator = lines.iterator();
        while (lineIterator.hasNext()) {
            String line = lineIterator.next();
            fullStreamData.append(line).append("\n");
            
            if (line.trim().isEmpty()) {
                currentEvent = null;
                continue;
            }
            
            // 解析event行
            if (line.startsWith("event:")) {
                currentEvent = line.substring(6).trim();
                log.debug("工作流事件类型: {}", currentEvent);
                continue;
            }
            
            // 解析data行
            if (line.startsWith("data:")) {
                String data = line.substring(5).trim();
                
                // 检查是否为结束标记
                if ("\"[DONE]\"".equals(data) || "[DONE]".equals(data)) {
                    log.info("收到工作流响应结束标记");
                    break;
                }
                
                if (data.isEmpty()) {
                    continue;
                }
                
                // 处理Message事件
                if ("Message".equals(currentEvent)) {
                    try {
                        JSONObject jsonData = JSON.parseObject(data);
                        String nodeType = jsonData.getString("node_type");
                        
                        // 只处理End节点的内容
                        if ("End".equals(nodeType)) {
                            String content = jsonData.getString("content");
                            if (content != null && !content.trim().isEmpty()) {
                                // 从content中提取output
                                String output = extractOutputFromContent(content);
                                if (output != null) {
                                    resultBuilder.append(output);
                                    log.info("成功提取工作流output内容，长度: {}", output.length());
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.warn("解析工作流Message数据失败: {}, 数据: {}", e.getMessage(), data);
                    }
                }
                // 处理Done事件
                else if ("Done".equals(currentEvent)) {
                    log.info("工作流执行完成");
                    break;
                }
            }
        }
        
        // 保存原始响应数据到API调用记录（包装成JSON格式）
        try {
            Map<String, Object> streamDataWrapper = new HashMap<>();
            streamDataWrapper.put("type", "workflow_stream");
            streamDataWrapper.put("data", fullStreamData.toString());
            streamDataWrapper.put("timestamp", System.currentTimeMillis());
            apiCall.setResponseBody(JSON.toJSONString(streamDataWrapper));
            cozeApiCallService.updateById(apiCall);
        } catch (Exception e) {
            log.error("保存工作流响应数据失败: {}", e.getMessage(), e);
        }
        
        String result = resultBuilder.toString();
        if (result.isEmpty()) {
            log.warn("工作流响应解析完成但内容为空，原始数据: {}", fullStreamData);
            throw new RuntimeException("AI响应解析失败：未能提取到有效内容");
        }
        
        return result;
    }
}