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

import cn.nianxx.thhotel.integrations.ai.superagent.common.request.SuperAgentMailDebugRequest;
import cn.nianxx.thhotel.integrations.ai.superagent.common.result.SuperAgentOpenApiResult;
import cn.nianxx.thhotel.integrations.ai.superagent.common.result.SuperAgentOpenApiTraceEvent;
import cn.nianxx.thhotel.integrations.ai.superagent.service.SuperAgentOpenApiClient;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientResponseException;

/**
 * SuperAgent Open API HTTP 客户端实现。负责创建 session、发送 SSE 消息和解析最终回答。
 */
@Service
public class SuperAgentOpenApiClientImpl implements SuperAgentOpenApiClient {

    private final SuperAgentOpenApiProperties properties;
    private final SuperAgentOpenApiSseParser sseParser;
    private final ObjectMapper objectMapper;

    /**
     * 注入 SuperAgent 配置、SSE 解析器和 JSON 工具。
     */
    public SuperAgentOpenApiClientImpl(
            SuperAgentOpenApiProperties properties,
            SuperAgentOpenApiSseParser sseParser,
            ObjectMapper objectMapper) {
        this.properties = properties;
        this.sseParser = sseParser;
        this.objectMapper = objectMapper;
    }

    /**
     * 调用 SuperAgent Open API 邮件 Debug 流程；配置缺失时直接失败，避免静默跳过真实调用。
     */
    @Override
    public SuperAgentOpenApiResult invokeMailDebug(
            SuperAgentMailDebugRequest request,
            Consumer<SuperAgentOpenApiTraceEvent> traceConsumer) {
        validateProperties();
        try {
            RestClient restClient = RestClient.builder()
                    .baseUrl(properties.getBaseUrl())
                    .requestFactory(requestFactory())
                    .build();
            String sessionId = createSession(restClient, request);
            return sendMessage(restClient, sessionId, request, traceConsumer);
        } catch (SuperAgentOpenApiException exception) {
            throw exception;
        } catch (Exception exception) {
            throw new SuperAgentOpenApiException("SuperAgent Open API 调用失败。", exception);
        }
    }

    /**
     * 创建 SuperAgent session。
     */
    private String createSession(RestClient restClient, SuperAgentMailDebugRequest request) throws Exception {
        String csrfToken = UUID.randomUUID().toString();
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("external_subject_id", properties.getExternalSubjectId());
        body.put("idempotency_key", request.idempotencyKey() + "-session");
        body.put("metadata", request.metadata());
        String response = restClient.post()
                .uri("/api/open/agent-sessions")
                .contentType(MediaType.APPLICATION_JSON)
                .header("Authorization", "Bearer " + properties.getApiKey())
                .header("X-CSRF-Token", csrfToken)
                .header("Cookie", "csrf_token=" + csrfToken)
                .body(body)
                .retrieve()
                .body(String.class);
        JsonNode json = objectMapper.readTree(response == null ? "{}" : response);
        String sessionId = text(json, "session_id");
        if (sessionId == null) {
            sessionId = text(json, "id");
        }
        if (sessionId == null) {
            throw new SuperAgentOpenApiException("SuperAgent 创建 session 响应缺少 session_id。");
        }
        return sessionId;
    }

    /**
     * 发送 Debug 邮件消息并流式解析 SSE 文本响应。
     */
    private SuperAgentOpenApiResult sendMessage(
            RestClient restClient,
            String sessionId,
            SuperAgentMailDebugRequest request,
            Consumer<SuperAgentOpenApiTraceEvent> traceConsumer) {
        String csrfToken = UUID.randomUUID().toString();
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("message", request.message());
        body.put("idempotency_key", request.idempotencyKey() + "-message");
        body.put("metadata", request.metadata());
        return restClient.post()
                .uri(uriBuilder -> uriBuilder
                        .path("/api/open/agent-sessions/{sessionId}/messages/stream")
                        .queryParam("include_trace", "true")
                        .build(sessionId))
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.TEXT_EVENT_STREAM)
                .header("Authorization", "Bearer " + properties.getApiKey())
                .header("X-CSRF-Token", csrfToken)
                .header("Cookie", "csrf_token=" + csrfToken)
                .body(body)
                .exchange((clientRequest, clientResponse) -> {
                    if (!clientResponse.getStatusCode().is2xxSuccessful()) {
                        byte[] responseBody = StreamUtils.copyToByteArray(clientResponse.getBody());
                        throw new RestClientResponseException(
                                "SuperAgent Open API HTTP 调用失败。",
                                clientResponse.getStatusCode(),
                                clientResponse.getStatusText(),
                                clientResponse.getHeaders(),
                                responseBody,
                                StandardCharsets.UTF_8);
                    }
                    try (InputStreamReader reader = new InputStreamReader(
                            clientResponse.getBody(),
                            StandardCharsets.UTF_8)) {
                        return sseParser.parse(sessionId, reader, traceConsumer);
                    }
                });
    }

    /**
     * 校验 SuperAgent Open API 必要配置。
     */
    private void validateProperties() {
        if (!properties.isEnabled()) {
            throw new SuperAgentOpenApiException("SuperAgent Open API 未启用。");
        }
        if (blank(properties.getBaseUrl()) || blank(properties.getApiKey()) || blank(properties.getExternalSubjectId())) {
            throw new SuperAgentOpenApiException("SuperAgent Open API 配置不完整。");
        }
    }

    /**
     * 构造带超时设置的 HTTP 请求工厂，避免 SSE 调用无限等待。
     */
    private SimpleClientHttpRequestFactory requestFactory() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(properties.getConnectTimeout());
        requestFactory.setReadTimeout(properties.getReadTimeout());
        return requestFactory;
    }

    /**
     * 读取 JSON 文本字段。
     */
    private String text(JsonNode json, String fieldName) {
        JsonNode value = json.path(fieldName);
        return value.isMissingNode() || value.isNull() || value.asText().isBlank() ? null : value.asText();
    }

    /**
     * 判断字符串是否为空白。
     */
    private boolean blank(String value) {
        return value == null || value.isBlank();
    }
}
