package org.xyzh.ai.client;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import jakarta.annotation.PostConstruct;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xyzh.ai.client.dto.*;
import org.xyzh.ai.client.callback.StreamCallback;
import org.xyzh.ai.config.DifyConfig;
import org.xyzh.ai.exception.DifyException;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @description Dify API客户端 - 封装所有Dify平台HTTP调用
 * @filename DifyApiClient.java
 * @author AI Assistant
 * @copyright xyzh
 * @since 2025-12-15
 */
@Component
public class DifyApiClient {

    private static final Logger logger = LoggerFactory.getLogger(DifyApiClient.class);

    @Autowired
    private DifyConfig difyConfig;

    private OkHttpClient httpClient;
    private OkHttpClient streamHttpClient;

    @PostConstruct
    public void init() {
        // 普通请求客户端
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(difyConfig.getConnectTimeout(), TimeUnit.SECONDS)
                .readTimeout(difyConfig.getReadTimeout(), TimeUnit.SECONDS)
                .writeTimeout(difyConfig.getTimeout(), TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .build();

        // 流式请求客户端（更长的读取超时）
        this.streamHttpClient = new OkHttpClient.Builder()
                .connectTimeout(difyConfig.getConnectTimeout(), TimeUnit.SECONDS)
                .readTimeout(difyConfig.getStreamTimeout(), TimeUnit.SECONDS)
                .writeTimeout(difyConfig.getTimeout(), TimeUnit.SECONDS)
                .retryOnConnectionFailure(false) // 流式不重试
                .build();

        logger.info("DifyApiClient初始化完成，API地址: {}", difyConfig.getApiBaseUrl());
    }

    // ===================== 知识库管理 API =====================

    /**
     * 创建知识库（Dataset）
     */
    public DatasetCreateResponse createDataset(DatasetCreateRequest request) {
        String url = difyConfig.getFullApiUrl("/datasets");

        try {
            String jsonBody = JSON.toJSONString(request);
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("创建知识库失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("创建知识库失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DatasetCreateResponse.class);
            }
        } catch (IOException e) {
            logger.error("创建知识库异常", e);
            throw new DifyException("创建知识库异常: " + e.getMessage(), e);
        }
    }

    /**
     * 查询知识库列表
     */
    public DatasetListResponse listDatasets(int page, int limit) {
        String url = difyConfig.getFullApiUrl("/datasets?page=" + page + "&limit=" + limit);

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("查询知识库列表失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("查询知识库列表失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DatasetListResponse.class);
            }
        } catch (IOException e) {
            logger.error("查询知识库列表异常", e);
            throw new DifyException("查询知识库列表异常: " + e.getMessage(), e);
        }
    }

    /**
     * 查询知识库详情
     */
    public DatasetDetailResponse getDatasetDetail(String datasetId) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId);

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("查询知识库详情失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("查询知识库详情失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DatasetDetailResponse.class);
            }
        } catch (IOException e) {
            logger.error("查询知识库详情异常", e);
            throw new DifyException("查询知识库详情异常: " + e.getMessage(), e);
        }
    }


    /**
     * 更新知识库
     */
    public void updateDataset(String datasetId, DatasetUpdateRequest request) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId);

        try {
            String jsonBody = JSON.toJSONString(request);
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .header("Content-Type", "application/json")
                    .patch(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String responseBody = response.body() != null ? response.body().string() : "";
                    logger.error("更新知识库失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("更新知识库失败: " + responseBody);
                }
                logger.info("知识库更新成功: {}", datasetId);
            }
        } catch (IOException e) {
            logger.error("更新知识库异常", e);
            throw new DifyException("更新知识库异常: " + e.getMessage(), e);
        }
    }
    /**
     * 删除知识库
     */
    public void deleteDataset(String datasetId) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId);

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .delete()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String responseBody = response.body() != null ? response.body().string() : "";
                    logger.error("删除知识库失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("删除知识库失败: " + responseBody);
                }
                logger.info("知识库删除成功: {}", datasetId);
            }
        } catch (IOException e) {
            logger.error("删除知识库异常", e);
            throw new DifyException("删除知识库异常: " + e.getMessage(), e);
        }
    }

    // ===================== 对话文件上传 API =====================
    
    /**
     * 上传文件用于对话（图文多模态）
     * @param file 文件
     * @param originalFilename 原始文件名
     * @param user 用户标识
     * @param apiKey API密钥
     * @return 文件信息（包含id、name、size等）
     */
    public DifyFileInfo uploadFileForChat(File file, String originalFilename, String user, String apiKey) {
        String url = difyConfig.getFullApiUrl("/files/upload");
        
        try {
            MultipartBody.Builder bodyBuilder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("file", originalFilename,
                            RequestBody.create(file, MediaType.parse("application/octet-stream")))
                    .addFormDataPart("user", user);

            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .post(bodyBuilder.build())
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("上传对话文件失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("上传对话文件失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DifyFileInfo.class);
            }
        } catch (IOException e) {
            logger.error("上传对话文件异常", e);
            throw new DifyException("上传对话文件异常: " + e.getMessage(), e);
        }
    }

    // ===================== 文档管理 API =====================

    /**
     * 上传文档到知识库（通过文件）
     * 根据 Dify API 文档: POST /datasets/{dataset_id}/document/create-by-file
     */
    public DocumentUploadResponse uploadDocumentByFile(
            String datasetId,
            File file,
            String originalFilename,
            DocumentUploadRequest uploadRequest) {

        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId + "/document/create-by-file");

        try {
            // 构建 data JSON 字符串（包含所有元数据）
            Map<String, Object> dataMap = new HashMap<>();
            if (uploadRequest.getName() != null) {
                dataMap.put("name", uploadRequest.getName());
            }
            if (uploadRequest.getIndexingTechnique() != null) {
                dataMap.put("indexing_technique", uploadRequest.getIndexingTechnique());
            }
            
            // process_rule 是必填字段，如果没有提供则使用默认配置
            if (uploadRequest.getProcessRule() != null) {
                dataMap.put("process_rule", uploadRequest.getProcessRule());
            } else {
                // 默认分段规则
                Map<String, Object> defaultProcessRule = new HashMap<>();
                defaultProcessRule.put("mode", "automatic");
                dataMap.put("process_rule", defaultProcessRule);
            }
            
            // 只保留官方支持的参数
            // doc_form 和 doc_language 不是请求参数，移除
            
            String dataJson = JSON.toJSONString(dataMap);
            logger.info("上传文档到知识库: datasetId={}, file={}, data={}", datasetId, originalFilename, dataJson);

            // 构建 multipart/form-data 请求体
            MultipartBody.Builder bodyBuilder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("file", originalFilename,
                            RequestBody.create(file, MediaType.parse("application/octet-stream")))
                    .addFormDataPart("data", dataJson);

            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .post(bodyBuilder.build())
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("上传文档失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("上传文档失败: " + responseBody);
                }

                logger.info("文档上传成功: datasetId={}, file={}", datasetId, originalFilename);
                return JSON.parseObject(responseBody, DocumentUploadResponse.class);
            }
        } catch (IOException e) {
            logger.error("上传文档异常", e);
            throw new DifyException("上传文档异常: " + e.getMessage(), e);
        }
    }

    /**
     * 查询文档处理状态
     */
    public DocumentStatusResponse getDocumentStatus(String datasetId, String batchId) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId + "/documents/" + batchId + "/indexing-status");

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("查询文档状态失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("查询文档状态失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DocumentStatusResponse.class);
            }
        } catch (IOException e) {
            logger.error("查询文档状态异常", e);
            throw new DifyException("查询文档状态异常: " + e.getMessage(), e);
        }
    }

    /**
     * 查询知识库文档列表
     */
    public DocumentListResponse listDocuments(String datasetId, int page, int limit) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId + "/documents?page=" + page + "&limit=" + limit);

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("查询文档列表失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("查询文档列表失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, DocumentListResponse.class);
            }
        } catch (IOException e) {
            logger.error("查询文档列表异常", e);
            throw new DifyException("查询文档列表异常: " + e.getMessage(), e);
        }
    }

    /**
     * 删除文档
     */
    public void deleteDocument(String datasetId, String documentId) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId + "/documents/" + documentId);

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .delete()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String responseBody = response.body() != null ? response.body().string() : "";
                    logger.error("删除文档失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("删除文档失败: " + responseBody);
                }
                logger.info("文档删除成功: {}", documentId);
            }
        } catch (IOException e) {
            logger.error("删除文档异常", e);
            throw new DifyException("删除文档异常: " + e.getMessage(), e);
        }
    }

    // ===================== 知识库检索 API =====================

    /**
     * 从知识库检索相关内容
     */
    public RetrievalResponse retrieveFromDataset(String datasetId, RetrievalRequest request) {
        String url = difyConfig.getFullApiUrl("/datasets/" + datasetId + "/retrieve");

        try {
            String jsonBody = JSON.toJSONString(request);
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("知识库检索失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("知识库检索失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, RetrievalResponse.class);
            }
        } catch (IOException e) {
            logger.error("知识库检索异常", e);
            throw new DifyException("知识库检索异常: " + e.getMessage(), e);
        }
    }

    // ===================== 对话 API =====================

    /**
     * 流式对话（SSE）
     */
    public void streamChat(ChatRequest request, String apiKey, StreamCallback callback) {
        String url = difyConfig.getFullApiUrl("/chat-messages");

        try {
            // 设置为流式模式
            request.setResponseMode("streaming");
            
            String jsonBody = JSON.toJSONString(request);
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            streamHttpClient.newCall(httpRequest).enqueue(new Callback() {
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (!response.isSuccessful()) {
                        String errorBody = response.body() != null ? response.body().string() : "";
                        callback.onError(new DifyException("流式对话失败: " + errorBody));
                        return;
                    }

                    try (BufferedReader reader = new BufferedReader(
                            new InputStreamReader(response.body().byteStream()))) {
                        
                        String line;
                        while ((line = reader.readLine()) != null) {
                            if (line.startsWith("data: ")) {
                                String data = line.substring(6).trim();
                                
                                if ("[DONE]".equals(data)) {
                                    callback.onComplete();
                                    break;
                                }
                                
                                if (!data.isEmpty()) {
                                    // 解析SSE数据
                                    JSONObject jsonNode = JSON.parseObject(data);
                                    String event = jsonNode.containsKey("event") ? jsonNode.getString("event") : "";
                                    
                                    // 转发事件给回调（用于前端SSE转发）
                                    callback.onEvent(event, data);
                                    
                                    switch (event) {
                                        case "message":
                                        case "agent_message":
                                            // 消息内容
                                            if (jsonNode.containsKey("answer")) {
                                                callback.onMessage(jsonNode.getString("answer"));
                                            }
                                            break;
                                        case "message_end":
                                            // 消息结束，提取元数据
                                            callback.onMessageEnd(data);
                                            break;
                                        case "error":
                                            // 错误事件
                                            String errorMsg = jsonNode.containsKey("message") ? 
                                                jsonNode.getString("message") : "未知错误";
                                            callback.onError(new DifyException(errorMsg));
                                            return;
                                        // 其他事件（workflow_started、node_started、node_finished等）
                                        // 已通过onEvent转发，这里不需要额外处理
                                    }
                                }
                            }
                        }
                        // 流正常读取完毕，如果没有收到 [DONE] 标记，也当作完成
                        logger.info("SSE流读取完毕");
                        callback.onComplete();
                    } catch (java.io.EOFException e) {
                        // EOFException 通常表示流正常结束（Dify可能没有发送[DONE]标记）
                        logger.info("SSE流已结束（EOF）");
                        callback.onComplete();
                    } catch (Exception e) {
                        logger.error("流式响应处理异常", e);
                        callback.onError(e);
                    }
                }

                @Override
                public void onFailure(Call call, IOException e) {
                    logger.error("流式对话请求失败", e);
                    callback.onError(e);
                }
            });

        } catch (Exception e) {
            logger.error("流式对话异常", e);
            callback.onError(e);
        }
    }

    /**
     * 阻塞式对话（非流式）
     */
    public ChatResponse blockingChat(ChatRequest request, String apiKey) {
        String url = difyConfig.getFullApiUrl("/chat-messages");

        try {
            // 设置为阻塞模式
            request.setResponseMode("blocking");
            
            String jsonBody = JSON.toJSONString(request);
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("阻塞式对话失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("阻塞式对话失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, ChatResponse.class);
            }
        } catch (IOException e) {
            logger.error("阻塞式对话异常", e);
            throw new DifyException("阻塞式对话异常: " + e.getMessage(), e);
        }
    }

    /**
     * 停止对话生成
     */
    public void stopChatMessage(String taskId, String userId, String apiKey) {
        String url = difyConfig.getFullApiUrl("/chat-messages/" + taskId + "/stop");

        try {
            String jsonBody = JSON.toJSONString(new StopRequest(userId));
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    String responseBody = response.body() != null ? response.body().string() : "";
                    logger.error("停止对话失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("停止对话失败: " + responseBody);
                }
                logger.info("对话停止成功: {}", taskId);
            }
        } catch (IOException e) {
            logger.error("停止对话异常", e);
            throw new DifyException("停止对话异常: " + e.getMessage(), e);
        }
    }

    /**
     * 提交消息反馈
     * @param messageId Dify消息ID
     * @param rating 评分（like/dislike/null）
     * @param userId 用户ID
     * @param apiKey API密钥
     */
    public void submitMessageFeedback(String messageId, String rating, String userId, String feedback, String apiKey) {
        String url = difyConfig.getFullApiUrl("/messages/" + messageId + "/feedbacks");

        try {
            FeedbackRequest feedbackRequest = new FeedbackRequest(rating, userId, feedback);
            String jsonBody = JSON.toJSONString(feedbackRequest);
            
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";

                if (!response.isSuccessful()) {
                    logger.error("提交消息反馈失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("提交消息反馈失败: " + responseBody);
                }
                if (responseBody!="success") {
                    logger.error("提交消息反馈失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("提交消息反馈失败: " + responseBody);
                }
                logger.info("消息反馈提交成功: {} - {}", messageId, rating);
            }
        } catch (IOException e) {
            logger.error("提交消息反馈异常", e);
            throw new DifyException("提交消息反馈异常: " + e.getMessage(), e);
        }
    }

    // ===================== 对话历史 API =====================

    /**
     * 获取对话历史消息
     */
    public MessageHistoryResponse getMessageHistory(
            String conversationId,
            String userId,
            String firstId,
            Integer limit,
            String apiKey) {
        
        StringBuilder urlBuilder = new StringBuilder(difyConfig.getFullApiUrl("/messages"));
        urlBuilder.append("?user=").append(userId);
        
        if (conversationId != null && !conversationId.isEmpty()) {
            urlBuilder.append("&conversation_id=").append(conversationId);
        }
        if (firstId != null && !firstId.isEmpty()) {
            urlBuilder.append("&first_id=").append(firstId);
        }
        if (limit != null) {
            urlBuilder.append("&limit=").append(limit);
        }

        try {
            Request httpRequest = new Request.Builder()
                    .url(urlBuilder.toString())
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("获取对话历史失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("获取对话历史失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, MessageHistoryResponse.class);
            }
        } catch (IOException e) {
            logger.error("获取对话历史异常", e);
            throw new DifyException("获取对话历史异常: " + e.getMessage(), e);
        }
    }

    /**
     * 获取对话列表
     */
    public ConversationListResponse getConversations(
            String userId,
            String lastId,
            Integer limit,
            String apiKey) {

        StringBuilder urlBuilder = new StringBuilder(difyConfig.getFullApiUrl("/conversations"));
        urlBuilder.append("?user=").append(userId);

        if (lastId != null && !lastId.isEmpty()) {
            urlBuilder.append("&last_id=").append(lastId);
        }
        if (limit != null) {
            urlBuilder.append("&limit=").append(limit);
        }

        try {
            Request httpRequest = new Request.Builder()
                    .url(urlBuilder.toString())
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";

                if (!response.isSuccessful()) {
                    logger.error("获取对话列表失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("获取对话列表失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, ConversationListResponse.class);
            }
        } catch (IOException e) {
            logger.error("获取对话列表异常", e);
            throw new DifyException("获取对话列表异常: " + e.getMessage(), e);
        }
    }

    /**
     * 获取对话变量
     * @param conversationId 会话ID
     * @param userId 用户标识
     * @param lastId 当前页最后面一条记录的ID,默认null
     * @param limit 一次请求返回多少条记录,默认20条,最大100条,最小1条
     * @param apiKey API密钥
     * @return 对话变量响应
     */
    public ConversationVariablesResponse getConversationVariables(
            String conversationId,
            String userId,
            String lastId,
            Integer limit,
            String apiKey) {

        StringBuilder urlBuilder = new StringBuilder(
                difyConfig.getFullApiUrl("/conversations/" + conversationId + "/variables"));
        urlBuilder.append("?user=").append(userId);

        if (lastId != null && !lastId.isEmpty()) {
            urlBuilder.append("&last_id=").append(lastId);
        }
        if (limit != null) {
            urlBuilder.append("&limit=").append(limit);
        }

        try {
            Request httpRequest = new Request.Builder()
                    .url(urlBuilder.toString())
                    .header("Authorization", "Bearer " + getApiKey(apiKey))
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";

                if (!response.isSuccessful()) {
                    logger.error("获取对话变量失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("获取对话变量失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, ConversationVariablesResponse.class);
            }
        } catch (IOException e) {
            logger.error("获取对话变量异常", e);
            throw new DifyException("获取对话变量异常: " + e.getMessage(), e);
        }
    }

    // ===================== 通用 HTTP 方法（用于代理转发）=====================

    /**
     * 通用 GET 请求
     * @param path API路径
     * @param apiKey API密钥（为null时使用知识库API Key）
     * @return JSON响应字符串
     */
    public String get(String path, String apiKey) {
        String url = difyConfig.getFullApiUrl(path);

        try {
            // 如果apiKey为null，使用知识库API Key（因为通用方法主要用于知识库相关操作）
            String actualApiKey = apiKey != null ? apiKey : getKnowledgeApiKey();
            
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + actualApiKey)
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("GET请求失败: {} - {} - {}", url, response.code(), responseBody);
                    throw new DifyException("GET请求失败[" + response.code() + "]: " + responseBody);
                }

                return responseBody;
            }
        } catch (IOException e) {
            logger.error("GET请求异常: {}", url, e);
            throw new DifyException("GET请求异常: " + e.getMessage(), e);
        }
    }

    /**
     * 通用 POST 请求
     * @param path API路径
     * @param requestBody 请求体（JSON字符串或Map）
     * @param apiKey API密钥（为null时使用知识库API Key）
     * @return JSON响应字符串
     */
    public String post(String path, Object requestBody, String apiKey) {
        String url = difyConfig.getFullApiUrl(path);

        try {
            // 如果apiKey为null，使用知识库API Key
            String actualApiKey = apiKey != null ? apiKey : getKnowledgeApiKey();
            
            String jsonBody = requestBody instanceof String ? 
                    (String) requestBody : JSON.toJSONString(requestBody);
            
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + actualApiKey)
                    .header("Content-Type", "application/json")
                    .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("POST请求失败: {} - {} - {}", url, response.code(), responseBody);
                    throw new DifyException("POST请求失败[" + response.code() + "]: " + responseBody);
                }

                return responseBody;
            }
        } catch (IOException e) {
            logger.error("POST请求异常: {}", url, e);
            throw new DifyException("POST请求异常: " + e.getMessage(), e);
        }
    }

    /**
     * 通用 PATCH 请求
     * @param path API路径
     * @param requestBody 请求体（JSON字符串或Map）
     * @param apiKey API密钥（为null时使用知识库API Key）
     * @return JSON响应字符串
     */
    public String patch(String path, Object requestBody, String apiKey) {
        String url = difyConfig.getFullApiUrl(path);

        try {
            // 如果apiKey为null，使用知识库API Key
            String actualApiKey = apiKey != null ? apiKey : getKnowledgeApiKey();
            
            String jsonBody = requestBody instanceof String ? 
                    (String) requestBody : JSON.toJSONString(requestBody);
            
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + actualApiKey)
                    .header("Content-Type", "application/json")
                    .patch(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("PATCH请求失败: {} - {} - {}", url, response.code(), responseBody);
                    throw new DifyException("PATCH请求失败[" + response.code() + "]: " + responseBody);
                }

                return responseBody;
            }
        } catch (IOException e) {
            logger.error("PATCH请求异常: {}", url, e);
            throw new DifyException("PATCH请求异常: " + e.getMessage(), e);
        }
    }

    /**
     * 通用 DELETE 请求
     * @param path API路径
     * @param apiKey API密钥（为null时使用知识库API Key）
     * @return JSON响应字符串
     */
    public String delete(String path, String apiKey) {
        String url = difyConfig.getFullApiUrl(path);

        try {
            // 如果apiKey为null，使用知识库API Key
            String actualApiKey = apiKey != null ? apiKey : getKnowledgeApiKey();
            
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + actualApiKey)
                    .delete()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("DELETE请求失败: {} - {} - {}", url, response.code(), responseBody);
                    throw new DifyException("DELETE请求失败[" + response.code() + "]: " + responseBody);
                }

                return responseBody;
            }
        } catch (IOException e) {
            logger.error("DELETE请求异常: {}", url, e);
            throw new DifyException("DELETE请求异常: " + e.getMessage(), e);
        }
    }

    // ===================== 工具方法 =====================

    /**
     * 获取API密钥（优先使用传入的密钥，否则使用配置的默认密钥）
     * 用于智能体相关的API
     */
    private String getApiKey(String apiKey) {
        if (apiKey != null && !apiKey.trim().isEmpty()) {
            return apiKey;
        }
        throw new DifyException("未配置Dify API密钥");
    }

    /**
     * 获取知识库API密钥（统一使用配置中的knowledgeApiKey）
     * 用于知识库相关的API
     */
    private String getKnowledgeApiKey() {
        if (difyConfig.getKnowledgeApiKey() != null && !difyConfig.getKnowledgeApiKey().trim().isEmpty()) {
            return difyConfig.getKnowledgeApiKey();
        }
        throw new DifyException("未配置Dify知识库API密钥");
    }

    /**
     * 停止请求的内部类
     */
    private static class StopRequest {
        private String user;

        public StopRequest(String user) {
            this.user = user;
        }

        public String getUser() {
            return user;
        }

        public void setUser(String user) {
            this.user = user;
        }
    }

    /**
     * 反馈请求的内部类
     */
    private static class FeedbackRequest {
        private String rating;
        private String user;

        private String feedback;

        public FeedbackRequest(String rating, String user, String feedback) {
            this.rating = rating;
            this.user = user;
            this.feedback = feedback;
        }

        public String getRating() {
            return rating;
        }

        public void setRating(String rating) {
            this.rating = rating;
        }

        public String getUser() {
            return user;
        }

        public void setUser(String user) {
            this.user = user;
        }

        public String getFeedback() {
            return feedback;
        }

        public void setFeedback(String feedback) {
            this.feedback = feedback;
        }
    }

    // ===================== 模型管理 API =====================

    /**
     * 获取可用的嵌入模型列表
     */
    public EmbeddingModelResponse getAvailableEmbeddingModels() {
        String url = difyConfig.getFullApiUrl("/workspaces/current/models/model-types/text-embedding");

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("获取嵌入模型列表失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("获取嵌入模型列表失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, EmbeddingModelResponse.class);
            }
        } catch (IOException e) {
            logger.error("获取嵌入模型列表异常", e);
            throw new DifyException("获取嵌入模型列表异常: " + e.getMessage(), e);
        }
    }

    /**
     * 获取可用的Rerank模型列表
     */
    public RerankModelResponse getAvailableRerankModels() {
        String url = difyConfig.getFullApiUrl("/workspaces/current/models/model-types/rerank");

        try {
            Request httpRequest = new Request.Builder()
                    .url(url)
                    .header("Authorization", "Bearer " + getKnowledgeApiKey())
                    .get()
                    .build();

            try (Response response = httpClient.newCall(httpRequest).execute()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                
                if (!response.isSuccessful()) {
                    logger.error("获取Rerank模型列表失败: {} - {}", response.code(), responseBody);
                    throw new DifyException("获取Rerank模型列表失败: " + responseBody);
                }

                return JSON.parseObject(responseBody, RerankModelResponse.class);
            }
        } catch (IOException e) {
            logger.error("获取Rerank模型列表异常", e);
            throw new DifyException("获取Rerank模型列表异常: " + e.getMessage(), e);
        }
    }
}

