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

import static org.assertj.core.api.Assertions.assertThat;

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 com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.net.httpserver.HttpServer;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Test;

class SuperAgentOpenApiClientImplTest {

    @Test
    void shouldRequestStreamingMessagesWithIncludeTraceAndEmitPublicTraceEvents() throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
        AtomicReference<String> streamQuery = new AtomicReference<>();
        server.createContext("/api/open/agent-sessions", exchange -> {
            byte[] response = "{\"session_id\":\"session-http-001\"}".getBytes(StandardCharsets.UTF_8);
            exchange.getResponseHeaders().add("Content-Type", "application/json");
            exchange.sendResponseHeaders(200, response.length);
            try (OutputStream outputStream = exchange.getResponseBody()) {
                outputStream.write(response);
            }
        });
        server.createContext("/api/open/agent-sessions/session-http-001/messages/stream", exchange -> {
            streamQuery.set(exchange.getRequestURI().getRawQuery());
            byte[] response = """
                    event: metadata
                    data: {"run_id":"run-http-001","resolved_profile_id":"profile-http","resolved_profile_version_id":"version-http"}

                    event: trace
                    data: {"event":"reasoning.summary","run_id":"run-http-001","text":"正在分析 Debug 邮件。","ts":"2026-07-11T10:00:01Z"}

                    event: values
                    data: {"messages":[{"type":"ai","content":"{\\"route_code\\":\\"S10\\"}","response_metadata":{"finish_reason":"stop","model_name":"debug-model"},"usage_metadata":{"input_tokens":9,"output_tokens":4,"total_tokens":13}}]}

                    event: end
                    data: {}

                    """.getBytes(StandardCharsets.UTF_8);
            exchange.getResponseHeaders().add("Content-Type", "text/event-stream");
            exchange.sendResponseHeaders(200, response.length);
            try (OutputStream outputStream = exchange.getResponseBody()) {
                outputStream.write(response);
            }
        });
        server.start();
        try {
            SuperAgentOpenApiProperties properties = new SuperAgentOpenApiProperties();
            properties.setEnabled(true);
            properties.setBaseUrl("http://127.0.0.1:" + server.getAddress().getPort());
            properties.setApiKey("df_open_test");
            properties.setExternalSubjectId("debug-subject");
            properties.setConnectTimeout(Duration.ofSeconds(5));
            properties.setReadTimeout(Duration.ofSeconds(5));
            SuperAgentOpenApiClientImpl client = new SuperAgentOpenApiClientImpl(
                    properties,
                    new SuperAgentOpenApiSseParser(new ObjectMapper()),
                    new ObjectMapper());
            List<SuperAgentOpenApiTraceEvent> traceEvents = new ArrayList<>();

            SuperAgentOpenApiResult result = client.invokeMailDebug(new SuperAgentMailDebugRequest(
                    "debug message",
                    "debug-idempotency",
                    Map.of("source", "unit-test")), traceEvents::add);

            assertThat(streamQuery.get()).isEqualTo("include_trace=true");
            assertThat(result.sessionId()).isEqualTo("session-http-001");
            assertThat(result.runId()).isEqualTo("run-http-001");
            assertThat(result.traceEvents()).hasSize(1);
            assertThat(traceEvents).hasSize(1);
            assertThat(traceEvents.get(0).event()).isEqualTo("reasoning.summary");
            assertThat(traceEvents.get(0).text()).isEqualTo("正在分析 Debug 邮件。");
        } finally {
            server.stop(0);
        }
    }
}
