package com.yinlihupo.enlish.service.utils; // 修改为你的包名

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO;
import com.yinlihupo.enlish.service.model.bo.Sentence;
import com.yinlihupo.framework.common.util.JsonUtils;
import lombok.Data;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class DifyClient {

    @Value("${ai.key}")
    private String apiKey;
    @Value("${ai.analyzeKey}")
    private String analyzeKey;
    @Value("${ai.sentenceKey}")
    private String sentenceKey;
    @Value("${ai.url}")
    private String baseUrl;
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper;

    // 构造函数
    public DifyClient() {

        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10)) // 连接超时
                .build();
        this.objectMapper = new ObjectMapper();
    }

    public List<Sentence> sendSentenceAnalyze(List<VocabularyBankDO> list, String grade) throws Exception {
        // 1. 构建请求体对象
        ChatRequest payload = new ChatRequest();
        payload.setQuery(JsonUtils.toJsonString(list.stream().map(VocabularyBankDO::getWord).toList()));
        payload.setUser("admin");

        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("grade", grade);
        payload.setResponseMode("blocking"); // 使用阻塞模式，一次性返回
        payload.setInputs(objectObjectHashMap);

        // 2. 序列化为 JSON 字符串
        String jsonBody = objectMapper.writeValueAsString(payload);

        // 3. 构建 HTTP 请求
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl))
                .header("Authorization", "Bearer " + sentenceKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .timeout(Duration.ofSeconds(30)) // 读取超时
                .build();

        // 4. 发送请求
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // 5. 检查状态码
        if (response.statusCode() != 200) {
            throw new RuntimeException("Dify 请求失败: HTTP " + response.statusCode() + " | Body: " + response.body());
        }

        // 6. 反序列化响应体
        DifyResponse difyResponse = objectMapper.readValue(response.body(), DifyResponse.class);

        String answer = difyResponse.getAnswer();
        answer = answer.replace("json", "");
        answer = answer.replace("```", "");

        return JsonUtils.parseList(answer, Sentence.class);

    }

    public DifyResponse sendStudentAnalyze(String query) throws Exception {
        String endpoint = this.baseUrl;

        // 1. 构建请求体对象
        ChatRequest payload = new ChatRequest();
        payload.setQuery(query);
        payload.setUser(String.valueOf(1));
        payload.setResponseMode("blocking"); // 使用阻塞模式，一次性返回
        payload.setInputs(new HashMap<>());

        // 2. 序列化为 JSON 字符串
        String jsonBody = objectMapper.writeValueAsString(payload);

        // 3. 构建 HTTP 请求
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .header("Authorization", "Bearer " + analyzeKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .timeout(Duration.ofSeconds(30)) // 读取超时
                .build();

        // 4. 发送请求
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // 5. 检查状态码
        if (response.statusCode() != 200) {
            throw new RuntimeException("Dify 请求失败: HTTP " + response.statusCode() + " | Body: " + response.body());
        }

        // 6. 反序列化响应体
        return objectMapper.readValue(response.body(), DifyResponse.class);
    }

    /**
     * 发送对话请求 (阻塞模式)
     *
     * @param query          用户的问题
     * @param userId         用户唯一标识
     * @param conversationId 会话ID (首次传 null 或 空字符串)
     * @return DifyResponse  包含回复内容和新的 conversationId
     */
    public DifyResponse sendChat(String query, String userId, String conversationId) throws Exception {
        String endpoint = this.baseUrl;

        // 1. 构建请求体对象
        ChatRequest payload = new ChatRequest();
        payload.setQuery(query);
        payload.setUser(userId);
        payload.setResponseMode("blocking"); // 使用阻塞模式，一次性返回
        // 如果有 conversationId，带上它以保持上下文
        if (conversationId != null && !conversationId.isEmpty()) {
            payload.setConversationId(conversationId);
        }
        // 如果你的 Dify 应用没有定义变量，inputs 传空 Map 即可，但字段必须存在
        payload.setInputs(new HashMap<>());

        // 2. 序列化为 JSON 字符串
        String jsonBody = objectMapper.writeValueAsString(payload);

        // 3. 构建 HTTP 请求
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(endpoint))
                .header("Authorization", "Bearer " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                .timeout(Duration.ofSeconds(30)) // 读取超时
                .build();

        // 4. 发送请求
        HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

        // 5. 检查状态码
        if (response.statusCode() != 200) {
            throw new RuntimeException("Dify 请求失败: HTTP " + response.statusCode() + " | Body: " + response.body());
        }

        // 6. 反序列化响应体
        return objectMapper.readValue(response.body(), DifyResponse.class);
    }

    // ================= 内部类：DTO (数据传输对象) =================

    // 请求体结构
    @Data
    @ToString
    public static class ChatRequest {
        private Map<String, Object> inputs;
        private String query;
        @JsonProperty("response_mode")
        private String responseMode;
        @JsonProperty("conversation_id")
        private String conversationId;
        private String user;

    }

    // 响应体结构
    // ignoreUnknown = true 非常重要：Dify 返回很多元数据，我们只映射需要的字段，防止报错
    @JsonIgnoreProperties(ignoreUnknown = true)
    @Data
    @ToString
    public static class DifyResponse {
        private String answer; // 核心回复内容

        @JsonProperty("conversation_id")
        private String conversationId; // 会话 ID

        @JsonProperty("message_id")
        private String messageId;

        private long created_at;

    }
}