package com.kt.ai.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kt.ai.circuitbreaker.CircuitBreakerManager;
import com.kt.ai.circuitbreaker.fallback.AIServiceFallback;
import com.kt.ai.client.ClaudeApiClient;
import com.kt.ai.client.dto.ClaudeRequest;
import com.kt.ai.client.dto.ClaudeResponse;
import com.kt.ai.model.dto.response.TrendAnalysis;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 트렌드 분석 서비스
 * - Claude AI를 통한 업종/지역/계절 트렌드 분석
 * - Circuit Breaker 적용
 *
 * @author AI Service Team
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TrendAnalysisService {

    private final ClaudeApiClient claudeApiClient;
    private final CircuitBreakerManager circuitBreakerManager;
    private final AIServiceFallback fallback;
    private final ObjectMapper objectMapper;

    @Value("${ai.claude.api-key}")
    private String apiKey;

    @Value("${ai.claude.anthropic-version}")
    private String anthropicVersion;

    @Value("${ai.claude.model}")
    private String model;

    @Value("${ai.claude.max-tokens}")
    private Integer maxTokens;

    @Value("${ai.claude.temperature}")
    private Double temperature;

    /**
     * 트렌드 분석 수행
     *
     * @param industry 업종
     * @param region   지역
     * @return 트렌드 분석 결과
     */
    public TrendAnalysis analyzeTrend(String industry, String region) {
        log.info("트렌드 분석 시작 - industry={}, region={}", industry, region);

        return circuitBreakerManager.executeWithCircuitBreaker(
                "claudeApi",
                () -> callClaudeApi(industry, region),
                () -> fallback.getDefaultTrendAnalysis(industry, region)
        );
    }

    /**
     * Claude API 호출
     */
    private TrendAnalysis callClaudeApi(String industry, String region) {
        // 프롬프트 생성
        String prompt = buildPrompt(industry, region);

        // Claude API 요청 생성
        ClaudeRequest request = ClaudeRequest.builder()
                .model(model)
                .messages(List.of(
                        ClaudeRequest.Message.builder()
                                .role("user")
                                .content(prompt)
                                .build()
                ))
                .maxTokens(maxTokens)
                .temperature(temperature)
                .system("당신은 마케팅 트렌드 분석 전문가입니다. 업종별, 지역별 트렌드를 분석하고 인사이트를 제공합니다.")
                .build();

        // API 호출
        log.debug("Claude API 호출 - model={}", model);
        ClaudeResponse response = claudeApiClient.sendMessage(
                apiKey,
                anthropicVersion,
                request
        );

        // 응답 파싱
        String responseText = response.extractText();
        log.debug("Claude API 응답 수신 - length={}", responseText.length());

        return parseResponse(responseText);
    }

    /**
     * 프롬프트 생성
     */
    private String buildPrompt(String industry, String region) {
        return String.format("""
                # 트렌드 분석 요청

                다음 조건에 맞는 마케팅 트렌드를 분석해주세요:
                - 업종: %s
                - 지역: %s

                ## 분석 요구사항
                1. **업종 트렌드**: 해당 업종에서 현재 주목받는 마케팅 트렌드 3개
                2. **지역 트렌드**: 해당 지역의 특성과 소비자 성향을 반영한 트렌드 2개
                3. **계절 트렌드**: 현재 계절(또는 다가오는 시즌)에 적합한 트렌드 2개

                ## 응답 형식
                응답은 반드시 다음 JSON 형식으로 작성해주세요:

                ```json
                {
                  "industryTrends": [
                    {
                      "keyword": "트렌드 키워드",
                      "relevance": 0.9,
                      "description": "트렌드에 대한 상세 설명 (2-3문장)"
                    }
                  ],
                  "regionalTrends": [
                    {
                      "keyword": "트렌드 키워드",
                      "relevance": 0.85,
                      "description": "트렌드에 대한 상세 설명 (2-3문장)"
                    }
                  ],
                  "seasonalTrends": [
                    {
                      "keyword": "트렌드 키워드",
                      "relevance": 0.8,
                      "description": "트렌드에 대한 상세 설명 (2-3문장)"
                    }
                  ]
                }
                ```

                ## 주의사항
                - relevance 값은 0.0 ~ 1.0 사이의 소수점 값
                - description은 구체적이고 실행 가능한 인사이트 포함
                - 한국 시장과 문화를 고려한 분석
                """, industry, region);
    }

    /**
     * Claude 응답 파싱
     */
    private TrendAnalysis parseResponse(String responseText) {
        try {
            // JSON 부분만 추출 (```json ... ``` 형태로 올 수 있음)
            String jsonText = extractJsonFromMarkdown(responseText);

            // JSON 파싱
            JsonNode rootNode = objectMapper.readTree(jsonText);

            // TrendAnalysis 객체 생성
            return TrendAnalysis.builder()
                    .industryTrends(parseTrendKeywords(rootNode.get("industryTrends")))
                    .regionalTrends(parseTrendKeywords(rootNode.get("regionalTrends")))
                    .seasonalTrends(parseTrendKeywords(rootNode.get("seasonalTrends")))
                    .build();

        } catch (JsonProcessingException e) {
            log.error("응답 파싱 실패", e);
            throw new RuntimeException("트렌드 분석 응답 파싱 중 오류 발생", e);
        }
    }

    /**
     * Markdown에서 JSON 추출
     */
    private String extractJsonFromMarkdown(String text) {
        // ```json ... ``` 형태에서 JSON만 추출
        if (text.contains("```json")) {
            int start = text.indexOf("```json") + 7;
            int end = text.indexOf("```", start);
            return text.substring(start, end).trim();
        }

        // ```{ ... }``` 형태에서 JSON만 추출
        if (text.contains("```")) {
            int start = text.indexOf("```") + 3;
            int end = text.indexOf("```", start);
            return text.substring(start, end).trim();
        }

        // 순수 JSON인 경우
        return text.trim();
    }

    /**
     * TrendKeyword 리스트 파싱
     */
    private List<TrendAnalysis.TrendKeyword> parseTrendKeywords(JsonNode arrayNode) {
        List<TrendAnalysis.TrendKeyword> keywords = new ArrayList<>();

        if (arrayNode != null && arrayNode.isArray()) {
            arrayNode.forEach(node -> {
                keywords.add(TrendAnalysis.TrendKeyword.builder()
                        .keyword(node.get("keyword").asText())
                        .relevance(node.get("relevance").asDouble())
                        .description(node.get("description").asText())
                        .build());
            });
        }

        return keywords;
    }
}
