package com.agent.management.config;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.ClientHttpRequestFactories;
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestClient;
import com.agent.management.common.LogRedactor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.stream.Collectors;

/**
 * Spring AI HTTP 请求/响应日志配置
 * 通过自定义 RestClient.Builder 拦截 Spring AI 发出的所有 HTTP 请求
 */
@Slf4j
@Configuration
public class AiRequestLoggingConfig {

    @Value("${spring.ai.openai.base-url:}")
    private String baseUrl;

    @Value("${spring.ai.openai.chat.completions-path:/v1/chat/completions}")
    private String completionsPath;

    @Value("${spring.ai.openai.chat.options.model:}")
    private String model;

    /**
     * 启动时打印 AI 连接配置
     */
    @PostConstruct
    public void logAiConfig() {
        log.info("[AI-CONFIG] ========== 大模型连接配置 ==========");
        log.info("[AI-CONFIG] base-url       : {}", baseUrl);
        log.info("[AI-CONFIG] completions-path: {}", completionsPath);
        log.info("[AI-CONFIG] model          : {}", model);
        log.info("[AI-CONFIG] 完整请求地址    : {}{}", baseUrl, completionsPath);
        log.info("[AI-CONFIG] =========================================");
    }

    /**
     * 自定义 RestClient.Builder，注入日志拦截器
     * Spring AI 1.0 的 OpenAiApi 使用 RestClient 发请求，会使用此 Builder
     */
    @Bean
    public RestClient.Builder restClientBuilder() {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(Duration.ofSeconds(10));
        requestFactory.setReadTimeout(Duration.ofSeconds(120));

        return RestClient.builder()
                .requestFactory(new BufferingClientHttpRequestFactory(requestFactory))
                .requestInterceptor(new AiLoggingInterceptor());
    }

    /**
     * HTTP 请求/响应日志拦截器
     */
    static class AiLoggingInterceptor implements ClientHttpRequestInterceptor {

        /**
         * LLM/智能体调用专用 logger：
         * 由 logback-spring.xml 中 LLM_HTTP logger 配置为 DEBUG 级别，仅写入独立日志文件，不输出到控制台。
         */
        private static final Logger LLM_HTTP = LoggerFactory.getLogger("LLM_HTTP");

        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body,
                                            ClientHttpRequestExecution execution) throws IOException {
            String url = request.getURI().toString();

            // === 打印请求信息 ===
            LLM_HTTP.debug("[AI-HTTP] ========== 请求开始 ==========");
            LLM_HTTP.debug("[AI-HTTP] 请求方法: {}", request.getMethod());
            LLM_HTTP.debug("[AI-HTTP] 请求 URL: {}", request.getURI());
            LLM_HTTP.debug("[AI-HTTP] 请求 Headers:");
            request.getHeaders().forEach((name, values) -> {
                // 脱敏处理 Authorization / api-key
                if (name.toLowerCase().contains("authorization") || name.toLowerCase().contains("api-key")) {
                    String val = values.iterator().next();
                    String masked = val.length() > 10
                            ? val.substring(0, 6) + "***" + val.substring(val.length() - 4)
                            : "***";
                    LLM_HTTP.debug("[AI-HTTP]   {}: {}", name, masked);
                } else {
                    LLM_HTTP.debug("[AI-HTTP]   {}: {}", name, values);
                }
            });

            String requestBody = new String(body, StandardCharsets.UTF_8);
            LLM_HTTP.debug("[AI-HTTP] 请求 Body ({} bytes): {}", body.length,
                    truncate(LogRedactor.redactVectors(requestBody), 2000));

            // === 执行请求 ===
            long startTime = System.currentTimeMillis();
            ClientHttpResponse response;
            try {
                response = execution.execute(request, body);
            } catch (IOException e) {
                long elapsed = System.currentTimeMillis() - startTime;
                // 失败仍走 ERROR 日志（输出到控制台 + 错误文件）
                log.error("[AI-HTTP] 请求失败, URL: {}, 耗时: {}ms, 异常: {}", url, elapsed, e.getMessage());
                log.error("[AI-HTTP] 异常堆栈:", e);
                throw e;
            }

            long elapsed = System.currentTimeMillis() - startTime;

            // === 打印响应信息 ===
            LLM_HTTP.debug("[AI-HTTP] 响应状态: {} {}, 耗时: {}ms, URL: {}",
                    response.getStatusCode().value(), response.getStatusText(), elapsed, url);
            LLM_HTTP.debug("[AI-HTTP] 响应 Headers:");
            response.getHeaders().forEach((name, values) ->
                    LLM_HTTP.debug("[AI-HTTP]   {}: {}", name, values));

            // 读取响应 body
            String responseBody;
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(response.getBody(), StandardCharsets.UTF_8))) {
                responseBody = reader.lines().collect(Collectors.joining("\n"));
            }
            LLM_HTTP.debug("[AI-HTTP] 响应 Body ({} chars): {}", responseBody.length(),
                    truncate(LogRedactor.redactVectors(responseBody), 3000));
            LLM_HTTP.debug("[AI-HTTP] ========== 请求结束 ==========");

            // 返回可重复读取的响应
            return new RepeatableClientHttpResponse(response, responseBody);
        }

        private String truncate(String text, int maxLen) {
            if (text == null) return "null";
            if (text.length() <= maxLen) return text;
            return text.substring(0, maxLen) + "...(截断，共 " + text.length() + " 字符)";
        }
    }

    /**
     * 可重复读取的 ClientHttpResponse 包装类
     */
    static class RepeatableClientHttpResponse implements ClientHttpResponse {
        private final ClientHttpResponse original;
        private final String body;

        RepeatableClientHttpResponse(ClientHttpResponse original, String body) {
            this.original = original;
            this.body = body;
        }

        @Override
        public org.springframework.http.HttpHeaders getHeaders() {
            return original.getHeaders();
        }

        @Override
        public java.io.InputStream getBody() {
            return new java.io.ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
        }

        @Override
        public org.springframework.http.HttpStatusCode getStatusCode() throws IOException {
            return original.getStatusCode();
        }

        @Override
        public String getStatusText() throws IOException {
            return original.getStatusText();
        }

        @Override
        public void close() {
            original.close();
        }
    }
}
