package com.example.demo.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Coze 工作流调用服务
 * 支持异步执行模式：提交任务后立即返回 executeId，通过轮询查询结果
 */
@Service
public class CozeWorkflowService {

    private static final Logger logger = LoggerFactory.getLogger(CozeWorkflowService.class);
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Value("${coze.api.base-url:https://api.coze.cn}")
    private String cozeBaseUrl;

    @Value("${coze.api.key:}")
    private String cozeApiKey;

    @Value("${coze.workflow.novel-comic-id:}")
    private String novelComicWorkflowId;

    @Value("${coze.bot.id:}")
    private String cozeBotId;

    // ==================== 异步执行模式 ====================

    /**
     * 异步提交工作流（立即返回 execute_id，不等待完成）
     * 调用 POST /v1/workflow/run 并设置 is_async=true
     *
     * @return Map 包含 success, executeId 或 message
     */
    public Map<String, Object> runWorkflowAsync(String workflowId, Map<String, Object> parameters) {
        Map<String, Object> result = new HashMap<>();

        if (cozeApiKey == null || cozeApiKey.isEmpty()) {
            result.put("success", false);
            result.put("message", "Coze API Key 未配置");
            return result;
        }
        if (workflowId == null || workflowId.isEmpty()) {
            result.put("success", false);
            result.put("message", "工作流 ID 未配置");
            return result;
        }

        try {
            String url = cozeBaseUrl + "/v1/workflow/run";

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("workflow_id", workflowId);
            requestBody.put("parameters", parameters);
            requestBody.put("is_async", true);
            if (cozeBotId != null && !cozeBotId.isEmpty()) {
                requestBody.put("bot_id", cozeBotId);
            }

            String bodyJson = objectMapper.writeValueAsString(requestBody);
            logger.info("异步提交 Coze 工作流: workflowId={}, botId={}", workflowId, cozeBotId);

            HttpResponse<String> response = Unirest.post(url)
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + cozeApiKey)
                    .body(bodyJson)
                    .asString();

            int statusCode = response.getStatus();
            String responseBody = response.getBody();
            logger.info("Coze 异步提交响应: status={}, body={}", statusCode,
                    responseBody != null ? responseBody.substring(0, Math.min(500, responseBody.length())) : "null");

            if (statusCode == 200) {
                JsonNode json = objectMapper.readTree(responseBody);
                int code = json.has("code") ? json.get("code").asInt(-1) : -1;

                if (code == 0) {
                    // 异步模式返回 execute_id
                    String executeId = json.has("execute_id") ? json.get("execute_id").asText() : null;
                    if (executeId == null && json.has("data")) {
                        executeId = json.get("data").asText();
                    }

                    if (executeId != null && !executeId.isEmpty()) {
                        result.put("success", true);
                        result.put("executeId", executeId);
                        logger.info("Coze 工作流异步提交成功: executeId={}", executeId);
                    } else {
                        result.put("success", false);
                        result.put("message", "未获取到 executeId");
                        logger.error("异步提交成功但未获取 executeId: {}", responseBody);
                    }
                } else {
                    String msg = json.has("msg") ? json.get("msg").asText() : "未知错误";
                    result.put("success", false);
                    result.put("message", "Coze 返回错误: " + msg);
                    logger.error("Coze 异步提交错误: code={}, msg={}", code, msg);
                }
            } else {
                result.put("success", false);
                result.put("message", "Coze API 请求失败，HTTP状态码: " + statusCode);
                logger.error("Coze 异步提交 HTTP 错误: status={}", statusCode);
            }

        } catch (Exception e) {
            logger.error("异步提交 Coze 工作流异常: workflowId={}", workflowId, e);
            result.put("success", false);
            result.put("message", "提交异常: " + e.getMessage());
        }

        return result;
    }

    /**
     * 查询异步工作流的执行状态
     * 调用 GET /v1/workflows/{workflow_id}/run_histories/{execute_id}
     * (基于 Coze 官方 SDK 源码确认的正确路径)
     *
     * @return Map 包含 status (RUNNING/SUCCESS/FAIL), data, message
     */
    public Map<String, Object> getWorkflowRunHistory(String workflowId, String executeId) {
        Map<String, Object> result = new HashMap<>();

        try {
            // 正确的 URL 格式（路径参数，非 query 参数）
            String url = cozeBaseUrl + "/v1/workflows/" + workflowId + "/run_histories/" + executeId;

            logger.debug("查询 Coze 工作流状态: workflowId={}, executeId={}, url={}", workflowId, executeId, url);

            HttpResponse<String> response = Unirest.get(url)
                    .header("Authorization", "Bearer " + cozeApiKey)
                    .asString();

            int statusCode = response.getStatus();
            String responseBody = response.getBody();

            logger.debug("Coze 状态查询响应: status={}, body={}", statusCode,
                    responseBody != null ? responseBody.substring(0, Math.min(500, responseBody.length())) : "null");

            if (statusCode == 200) {
                JsonNode json = objectMapper.readTree(responseBody);
                int code = json.has("code") ? json.get("code").asInt(-1) : -1;

                if (code == 0) {
                    // data 是数组，取第一个元素（与 SDK 一致：res.data[0]）
                    JsonNode dataNode = json.get("data");
                    JsonNode historyItem = null;
                    if (dataNode != null) {
                        if (dataNode.isArray() && dataNode.size() > 0) {
                            historyItem = dataNode.get(0);
                        } else if (dataNode.isObject()) {
                            historyItem = dataNode;
                        }
                    }

                    if (historyItem != null) {
                        // execute_status 是字符串: "Success" / "Running" / "Fail"
                        String execStatus = historyItem.has("execute_status")
                                ? historyItem.get("execute_status").asText() : "Running";

                        switch (execStatus) {
                            case "Success":
                                result.put("status", "SUCCESS");
                                String output = historyItem.has("output") ? historyItem.get("output").asText() : "";
                                // 尝试解析 output 为 JSON
                                try {
                                    JsonNode outputJson = objectMapper.readTree(output);
                                    result.put("data", objectMapper.convertValue(outputJson, Object.class));
                                } catch (Exception e) {
                                    result.put("data", output);
                                }
                                logger.info("Coze 工作流执行成功: executeId={}", executeId);
                                break;

                            case "Running":
                                result.put("status", "RUNNING");
                                logger.debug("Coze 工作流仍在运行: executeId={}", executeId);
                                break;

                            case "Fail":
                                result.put("status", "FAIL");
                                String errMsg = historyItem.has("error_message")
                                        ? historyItem.get("error_message").asText() : "工作流执行失败";
                                result.put("message", errMsg);
                                logger.error("Coze 工作流执行失败: executeId={}, error={}", executeId, errMsg);
                                break;

                            default:
                                // 未知状态，当作运行中
                                result.put("status", "RUNNING");
                                logger.warn("Coze 工作流未知状态: executeId={}, status={}", executeId, execStatus);
                                break;
                        }
                    } else {
                        result.put("status", "RUNNING");
                    }
                } else {
                    String msg = json.has("msg") ? json.get("msg").asText() : "查询失败";
                    result.put("status", "FAIL");
                    result.put("message", msg);
                    logger.error("查询工作流状态失败: code={}, msg={}", code, msg);
                }
            } else {
                result.put("status", "FAIL");
                result.put("message", "查询状态 HTTP 错误: " + statusCode);
                logger.error("查询工作流状态 HTTP 错误: status={}, body={}", statusCode, responseBody);
            }

        } catch (Exception e) {
            logger.error("查询工作流状态异常: executeId={}", executeId, e);
            result.put("status", "FAIL");
            result.put("message", "查询异常: " + e.getMessage());
        }

        return result;
    }

    // ==================== 小说漫剧业务方法 ====================

    /**
     * 异步提交小说漫剧生成工作流
     *
     * @return Map 包含 success, executeId
     */
    public Map<String, Object> generateNovelComicAsync(String theme, String storyBackground,
                                                        String musicUrl, String storyScript) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("title", theme != null ? theme : "");
        parameters.put("beijing", storyBackground);
        parameters.put("text", storyScript);
        parameters.put("bgm", musicUrl != null ? musicUrl : "");

        logger.info("异步提交小说漫剧: title={}, beijing长度={}, bgm={}, text长度={}",
                parameters.get("title"),
                storyBackground != null ? storyBackground.length() : 0,
                musicUrl != null && !musicUrl.isEmpty() ? musicUrl : "(空)",
                storyScript != null ? storyScript.length() : 0);

        return runWorkflowAsync(novelComicWorkflowId, parameters);
    }

    /**
     * 查询小说漫剧生成任务状态
     */
    public Map<String, Object> getNovelComicStatus(String executeId) {
        return getWorkflowRunHistory(novelComicWorkflowId, executeId);
    }

    /**
     * 获取当前配置状态
     */
    public Map<String, Object> getConfigStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("baseUrl", cozeBaseUrl);
        status.put("apiKeyConfigured", cozeApiKey != null && !cozeApiKey.isEmpty());
        status.put("apiKeyLength", cozeApiKey != null ? cozeApiKey.length() : 0);
        status.put("apiKeyPrefix", cozeApiKey != null && cozeApiKey.length() > 10
                ? cozeApiKey.substring(0, 10) + "..." : "empty");
        status.put("novelComicWorkflowId", novelComicWorkflowId != null && !novelComicWorkflowId.isEmpty()
                ? novelComicWorkflowId : "未配置");
        status.put("botId", cozeBotId != null && !cozeBotId.isEmpty() ? cozeBotId : "未配置");
        return status;
    }
}
