package cn.nianxx.thhotel.integrations.ai.superagent.service.impl;

import cn.nianxx.thhotel.integrations.ai.superagent.common.result.SuperAgentOpenApiResult;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.springframework.stereotype.Component;

/**
 * SuperAgent SSE 响应解析器。优先从 values.messages 中提取 finish_reason=stop 的最终 AI 回答。
 */
@Component
public class SuperAgentOpenApiSseParser {

    private final ObjectMapper objectMapper;

    /**
     * 使用默认 ObjectMapper，便于单元测试直接 new。
     */
    public SuperAgentOpenApiSseParser() {
        this(new ObjectMapper());
    }

    /**
     * 注入 JSON 解析器。
     */
    public SuperAgentOpenApiSseParser(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    /**
     * 解析 SSE 文本，返回最终 AI 回答和调用元数据。
     */
    public SuperAgentOpenApiResult parse(String sessionId, String sseBody) {
        if (sseBody == null || sseBody.isBlank()) {
            throw new SuperAgentOpenApiException("SuperAgent SSE 响应为空。");
        }
        Set<String> eventTypes = new LinkedHashSet<>();
        ParsedState state = new ParsedState();
        for (SseEvent event : splitEvents(sseBody)) {
            eventTypes.add(event.eventType());
            consumeEvent(event, state);
        }
        if (state.rawAnswer == null || state.rawAnswer.isBlank()) {
            throw new SuperAgentOpenApiException("SuperAgent SSE 未找到最终 AI 回答。");
        }
        return new SuperAgentOpenApiResult(
                sessionId,
                state.runId,
                state.profileId,
                state.profileVersionId,
                state.modelName,
                state.rawAnswer,
                state.inputTokens,
                state.outputTokens,
                state.totalTokens,
                List.copyOf(eventTypes));
    }

    /**
     * 消费单个 SSE 事件。
     */
    private void consumeEvent(SseEvent event, ParsedState state) {
        try {
            JsonNode data = objectMapper.readTree(event.data());
            if ("metadata".equals(event.eventType())) {
                state.runId = text(data, "run_id", state.runId);
                state.profileId = text(data, "resolved_profile_id", state.profileId);
                state.profileVersionId = text(data, "resolved_profile_version_id", state.profileVersionId);
            }
            if ("values".equals(event.eventType())) {
                consumeValuesEvent(data, state);
            }
        } catch (Exception exception) {
            throw new SuperAgentOpenApiException("SuperAgent SSE JSON 解析失败。", exception);
        }
    }

    /**
     * 从 values.messages 中提取最终 AI 消息和 token 用量。
     */
    private void consumeValuesEvent(JsonNode data, ParsedState state) {
        JsonNode messages = data.path("messages");
        if (!messages.isArray()) {
            return;
        }
        for (JsonNode message : messages) {
            if (!"ai".equals(message.path("type").asText())) {
                continue;
            }
            String finishReason = message.path("response_metadata").path("finish_reason").asText();
            String content = message.path("content").asText(null);
            if ("stop".equals(finishReason) && content != null && !content.isBlank()) {
                state.rawAnswer = content;
                state.modelName = text(message.path("response_metadata"), "model_name", state.modelName);
                JsonNode usage = message.path("usage_metadata");
                state.inputTokens = intValue(usage, "input_tokens", state.inputTokens);
                state.outputTokens = intValue(usage, "output_tokens", state.outputTokens);
                state.totalTokens = intValue(usage, "total_tokens", state.totalTokens);
            }
        }
    }

    /**
     * 拆分 SSE 事件块，支持多行 data。
     */
    private List<SseEvent> splitEvents(String sseBody) {
        String[] blocks = sseBody.split("\\R\\s*\\R");
        List<SseEvent> events = new ArrayList<>();
        for (String block : blocks) {
            String eventType = "message";
            StringBuilder data = new StringBuilder();
            for (String line : block.split("\\R")) {
                if (line.startsWith("event:")) {
                    eventType = line.substring("event:".length()).trim();
                    continue;
                }
                if (line.startsWith("data:")) {
                    if (!data.isEmpty()) {
                        data.append('\n');
                    }
                    data.append(line.substring("data:".length()).trim());
                }
            }
            if (!data.isEmpty()) {
                events.add(new SseEvent(eventType, data.toString()));
            }
        }
        return events;
    }

    /**
     * 读取文本字段，缺失时保留已有值。
     */
    private String text(JsonNode node, String fieldName, String fallback) {
        JsonNode value = node.path(fieldName);
        return value.isMissingNode() || value.isNull() ? fallback : value.asText();
    }

    /**
     * 读取整数字段，缺失时保留已有值。
     */
    private Integer intValue(JsonNode node, String fieldName, Integer fallback) {
        JsonNode value = node.path(fieldName);
        return value.isMissingNode() || value.isNull() ? fallback : value.asInt();
    }

    /**
     * SSE 单事件。
     */
    private record SseEvent(String eventType, String data) {
    }

    /**
     * SSE 解析过程中的可变状态。
     */
    private static final class ParsedState {
        private String runId;
        private String profileId;
        private String profileVersionId;
        private String modelName;
        private String rawAnswer;
        private Integer inputTokens;
        private Integer outputTokens;
        private Integer totalTokens;
    }
}
