package com.zioinfo.esn.ai.controller;

import com.zioinfo.esn.admin.AuditService;
import com.zioinfo.esn.ai.dto.AiFeedbackRequest;
import com.zioinfo.esn.ai.learning.LocalLearningStore;
import com.zioinfo.esn.common.ApiResponse;
import com.zioinfo.esn.rag.EsnRagClient;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * AI 답변 피드백 수집(👍/👎 + 교정). [GUARDiA-ESN]
 *
 * <p>{@code POST /api/ai/feedback} — 인증 사용자면 누구나 제출(SecurityConfig POST /api/** 일반 규칙).
 * 로컬 DuckDB({@link LocalLearningStore}, 오프라인 AI 분석)와 중앙 guardia-rag({@link EsnRagClient#feedback},
 * 통합 학습·평가 게이트)에 <b>둘 다</b> 기록한다. 어느 한쪽 실패가 다른 쪽/응답을 막지 않는다(best-effort).
 *
 * <p><b>보안 불변</b>: 저장 전 PII 마스킹(LocalLearningStore). 사용자 식별자는 마스킹. 자격증명 미기록.
 * 응답은 저장 성공 여부 요약만 반환(원문/키/스택 미노출).
 */
@RestController
@RequestMapping("/api/ai/feedback")
@RequiredArgsConstructor
public class AiFeedbackController {

    private final LocalLearningStore learningStore;
    private final EsnRagClient ragClient;

    @PostMapping
    public ApiResponse<Map<String, Object>> submit(@RequestBody AiFeedbackRequest req) {
        String actor = AuditService.currentActor();
        String verdict = req.verdict() == null ? "unknown" : req.verdict().trim();

        // 1) 로컬 DuckDB 기록(마스킹은 저장 계층에서 수행) — best-effort
        boolean storedLocal = false;
        try {
            learningStore.recordFeedback(req.feature(), req.question(), req.answer(),
                    verdict, req.correction(), actor);
            storedLocal = learningStore.isAvailable();
        } catch (Exception ignore) {
            // no-op — 무영향
        }

        // 2) 중앙 guardia-rag /feedback 전달(테넌트 격리) — best-effort
        boolean forwarded = false;
        try {
            Map<String, Object> res = ragClient.feedback(
                    req.tenantCode(), req.answerId(), req.question(), req.answer(),
                    verdict, req.correction(), LocalLearningStore.maskUser(actor));
            Object stored = res == null ? null : res.get("stored");
            forwarded = Boolean.TRUE.equals(stored);
        } catch (Exception ignore) {
            // no-op — 중앙 미가용은 degraded, 로컬 기록으로 무손실
        }

        Map<String, Object> out = new LinkedHashMap<>();
        out.put("storedLocal", storedLocal);
        out.put("forwardedCentral", forwarded);
        return ApiResponse.ok("피드백이 접수되었습니다.", out);
    }
}
