package com.unicorn.hgzero.meeting.infra.gateway;

import com.unicorn.hgzero.meeting.biz.dto.AiAnalysisDTO;
import com.unicorn.hgzero.meeting.infra.cache.CacheService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Optional;

/**
 * AI 서비스 연동 Gateway
 * Redis 캐시 우선 방식으로 AI 분석 결과 조회
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class AiServiceGateway {

    private final CacheService cacheService;
    private final RestTemplate restTemplate;

    @Value("${ai.service.base-url:http://ai:8080}")
    private String aiServiceBaseUrl;

    @Value("${ai.service.timeout-ms:5000}")
    private int timeoutMs;

    /**
     * 회의록 AI 분석 요청 및 결과 조회 (캐시 우선)
     * 
     * @param minutesId 회의록 ID
     * @param content 분석할 회의록 내용
     * @return AI 분석 결과 DTO
     */
    public Optional<AiAnalysisDTO> getAiAnalysis(String minutesId, String content) {
        try {
            // 1. Redis 캐시에서 먼저 조회
            Optional<AiAnalysisDTO> cachedResult = getCachedAiAnalysis(minutesId);
            if (cachedResult.isPresent()) {
                log.debug("AI 분석 결과 캐시 히트 - minutesId: {}", minutesId);
                return cachedResult;
            }

            // 2. 캐시 미스 시 AI 서비스 직접 호출
            log.debug("AI 분석 결과 캐시 미스, AI 서비스 호출 - minutesId: {}", minutesId);
            Optional<AiAnalysisDTO> analysisResult = requestAiAnalysis(minutesId, content);
            
            // 3. 분석 결과가 있으면 캐시에 저장 (TTL: 1시간)
            if (analysisResult.isPresent()) {
                cacheAiAnalysis(minutesId, analysisResult.get());
            }
            
            return analysisResult;

        } catch (Exception e) {
            log.error("AI 분석 요청 실패 - minutesId: {}", minutesId, e);
            return Optional.empty();
        }
    }

    /**
     * Redis 캐시에서 AI 분석 결과 조회
     */
    private Optional<AiAnalysisDTO> getCachedAiAnalysis(String minutesId) {
        try {
            return cacheService.getAiAnalysis(minutesId);
        } catch (Exception e) {
            log.warn("AI 분석 캐시 조회 실패 - minutesId: {}", minutesId, e);
            return Optional.empty();
        }
    }

    /**
     * AI 서비스에 직접 분석 요청
     */
    private Optional<AiAnalysisDTO> requestAiAnalysis(String minutesId, String content) {
        try {
            // HTTP 헤더 설정
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("X-Request-Source", "meeting-service");
            headers.add("X-Minutes-Id", minutesId);

            // 요청 바디 구성
            Map<String, Object> requestBody = Map.of(
                "minutesId", minutesId,
                "content", content,
                "analysisType", "COMPREHENSIVE", // 종합 분석
                "features", new String[]{
                    "KEY_POINTS",     // 핵심내용 추출
                    "KEYWORDS",       // 키워드 추출  
                    "DECISIONS",      // 결정사항 추출
                    "SUMMARY",        // 요약
                    "RELATED_MINUTES" // 관련회의록 추천
                }
            );

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            // AI 서비스 호출
            String aiAnalysisUrl = aiServiceBaseUrl + "/api/v1/analysis/minutes";
            ResponseEntity<AiAnalysisDTO> response = restTemplate.exchange(
                aiAnalysisUrl,
                HttpMethod.POST,
                request,
                AiAnalysisDTO.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                log.info("AI 분석 완료 - minutesId: {}", minutesId);
                return Optional.of(response.getBody());
            } else {
                log.warn("AI 서비스 응답 비정상 - minutesId: {}, status: {}", 
                        minutesId, response.getStatusCode());
                return Optional.empty();
            }

        } catch (Exception e) {
            log.error("AI 서비스 호출 실패 - minutesId: {}, error: {}", minutesId, e.getMessage(), e);
            return Optional.empty();
        }
    }

    /**
     * AI 분석 결과를 Redis 캐시에 저장
     */
    private void cacheAiAnalysis(String minutesId, AiAnalysisDTO analysisResult) {
        try {
            cacheService.cacheAiAnalysis(minutesId, analysisResult);
            log.debug("AI 분석 결과 캐시 저장 완료 - minutesId: {}", minutesId);
        } catch (Exception e) {
            log.warn("AI 분석 결과 캐시 저장 실패 - minutesId: {}", minutesId, e);
            // 캐시 저장 실패는 비즈니스에 영향주지 않으므로 로그만 남김
        }
    }

    /**
     * AI 분석 상태 확인
     * 
     * @param minutesId 회의록 ID
     * @return 분석 상태 (PENDING, IN_PROGRESS, COMPLETED, FAILED)
     */
    public String getAnalysisStatus(String minutesId) {
        try {
            String statusUrl = aiServiceBaseUrl + "/api/v1/analysis/status/" + minutesId;
            
            HttpHeaders headers = new HttpHeaders();
            headers.add("X-Request-Source", "meeting-service");
            HttpEntity<Void> request = new HttpEntity<>(headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                statusUrl,
                HttpMethod.GET,
                request,
                Map.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                return (String) response.getBody().get("status");
            }

            return "UNKNOWN";

        } catch (Exception e) {
            log.warn("AI 분석 상태 조회 실패 - minutesId: {}", minutesId, e);
            return "UNKNOWN";
        }
    }

    /**
     * AI 분석 캐시 무효화
     */
    public void evictAiAnalysisCache(String minutesId) {
        try {
            cacheService.evictAiAnalysisCache(minutesId);
            log.debug("AI 분석 캐시 무효화 완료 - minutesId: {}", minutesId);
        } catch (Exception e) {
            log.warn("AI 분석 캐시 무효화 실패 - minutesId: {}", minutesId, e);
        }
    }
}