package com.zioinfo.hrm.ai.learning;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

/**
 * 피드백을 중앙 guardia-rag {@code /feedback} 로 best-effort 전달(통합 학습·평가 게이트). [GUARDiA-HRM]
 *
 * <p><b>온프레미스 전용</b>: base-url 은 서버 내부 루프백(127.0.0.1:8020) — 외부 URL 금지.
 * 실패(미가용/타임아웃/비활성)는 조용히 무시한다 — 로컬 DuckDB 적재가 1차 저장소이므로 무회귀.
 * 페이로드의 텍스트는 이미 {@link PiiMasker} 로 마스킹된 값만 전달한다.
 *
 * <p><b>레퍼런스</b>: guardia-bi {@code ai.learning.CentralFeedbackForwarder} 미러(RagProperties→@Value).
 */
@Slf4j
@Component
public class CentralFeedbackForwarder {

    /** 중앙 guardia-rag 베이스 URL(서버 내부 루프백 기본). 외부 URL 설정 금지. */
    @Value("${guardia.rag.base-url:http://127.0.0.1:8020}")
    private String ragBaseUrl;

    /** RAG 경유 마스터 스위치. false 면 전달 스킵(로컬 DuckDB 적재만). */
    @Value("${guardia.rag.enabled:true}")
    private boolean ragEnabled;

    /** 중앙 rag 로 피드백 전달(마스킹된 값). 실패는 무시. */
    public void forward(String feature, String maskedQuestion, String maskedAnswer,
                        String verdict, String maskedCorrection) {
        if (!ragEnabled) {
            return;
        }
        try {
            String url = trimTrailingSlash(ragBaseUrl) + "/feedback";
            String payload = "{"
                    + "\"solution\":\"" + LearningStore.SOLUTION + "\","
                    + "\"feature\":" + json(feature) + ","
                    + "\"query\":" + json(maskedQuestion) + ","
                    + "\"answer\":" + json(maskedAnswer) + ","
                    + "\"verdict\":" + json(verdict) + ","
                    + "\"correction\":" + json(maskedCorrection)
                    + "}";
            HttpClient client = HttpClient.newBuilder()
                    .connectTimeout(Duration.ofSeconds(3))
                    .build();
            HttpRequest req = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .timeout(Duration.ofSeconds(5))
                    .header("content-type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(payload))
                    .build();
            client.send(req, HttpResponse.BodyHandlers.discarding());
        } catch (Exception e) {
            log.warn("중앙 rag 피드백 전달 실패(무시): {}", e.getClass().getSimpleName());
        }
    }

    private static String trimTrailingSlash(String s) {
        if (s == null || s.isBlank()) {
            return "http://127.0.0.1:8020";
        }
        return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
    }

    private static String json(String s) {
        if (s == null) {
            return "\"\"";
        }
        StringBuilder sb = new StringBuilder("\"");
        for (char c : s.toCharArray()) {
            switch (c) {
                case '"' -> sb.append("\\\"");
                case '\\' -> sb.append("\\\\");
                case '\n' -> sb.append("\\n");
                case '\r' -> sb.append("\\r");
                case '\t' -> sb.append("\\t");
                default -> {
                    if (c < 0x20) {
                        sb.append(String.format("\\u%04x", (int) c));
                    } else {
                        sb.append(c);
                    }
                }
            }
        }
        return sb.append("\"").toString();
    }
}
