package com.kt.event.analytics.service;

import com.kt.event.analytics.entity.ChannelStats;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 외부 채널 Service
 *
 * 외부 API 호출 및 Circuit Breaker 적용
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ExternalChannelService {

    /**
     * 외부 채널 API에서 통계 업데이트
     *
     * @param eventId          이벤트 ID
     * @param channelStatsList 채널 통계 목록
     */
    public void updateChannelStatsFromExternalAPIs(String eventId, List<ChannelStats> channelStatsList) {
        log.info("외부 채널 API 병렬 호출 시작: eventId={}", eventId);

        List<CompletableFuture<Void>> futures = channelStatsList.stream()
            .map(channelStats -> CompletableFuture.runAsync(() ->
                updateChannelStatsFromAPI(eventId, channelStats)))
            .toList();

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        log.info("외부 채널 API 병렬 호출 완료: eventId={}", eventId);
    }

    /**
     * 개별 채널 통계 업데이트
     */
    private void updateChannelStatsFromAPI(String eventId, ChannelStats channelStats) {
        String channelName = channelStats.getChannelName();
        log.debug("채널 통계 업데이트: eventId={}, channel={}", eventId, channelName);

        switch (channelName) {
            case "우리동네TV" -> updateWooriTVStats(eventId, channelStats);
            case "지니TV" -> updateGenieTVStats(eventId, channelStats);
            case "링고비즈" -> updateRingoBizStats(eventId, channelStats);
            case "SNS" -> updateSNSStats(eventId, channelStats);
            default -> log.warn("알 수 없는 채널: {}", channelName);
        }
    }

    /**
     * 우리동네TV 통계 업데이트
     */
    @CircuitBreaker(name = "wooriTV", fallbackMethod = "wooriTVFallback")
    private void updateWooriTVStats(String eventId, ChannelStats channelStats) {
        log.debug("우리동네TV API 호출: eventId={}", eventId);
        // 실제 API 호출 로직 (Feign Client 사용)
        // 예시 데이터 설정
        channelStats.setViews(45000);
        channelStats.setClicks(5500);
        channelStats.setImpressions(120000);
    }

    /**
     * 우리동네TV Fallback
     */
    private void wooriTVFallback(String eventId, ChannelStats channelStats, Exception e) {
        log.warn("우리동네TV API 장애, Fallback 실행: eventId={}, error={}", eventId, e.getMessage());
        // Fallback 데이터 (캐시 또는 기본값)
        channelStats.setViews(0);
        channelStats.setClicks(0);
    }

    /**
     * 지니TV 통계 업데이트
     */
    @CircuitBreaker(name = "genieTV", fallbackMethod = "genieTVFallback")
    private void updateGenieTVStats(String eventId, ChannelStats channelStats) {
        log.debug("지니TV API 호출: eventId={}", eventId);
        // 예시 데이터 설정
        channelStats.setViews(30000);
        channelStats.setClicks(3000);
        channelStats.setImpressions(80000);
    }

    /**
     * 지니TV Fallback
     */
    private void genieTVFallback(String eventId, ChannelStats channelStats, Exception e) {
        log.warn("지니TV API 장애, Fallback 실행: eventId={}, error={}", eventId, e.getMessage());
        channelStats.setViews(0);
        channelStats.setClicks(0);
    }

    /**
     * 링고비즈 통계 업데이트
     */
    @CircuitBreaker(name = "ringoBiz", fallbackMethod = "ringoBizFallback")
    private void updateRingoBizStats(String eventId, ChannelStats channelStats) {
        log.debug("링고비즈 API 호출: eventId={}", eventId);
        // 예시 데이터 설정
        channelStats.setTotalCalls(3000);
        channelStats.setCompletedCalls(2500);
        channelStats.setAverageDuration(45);
    }

    /**
     * 링고비즈 Fallback
     */
    private void ringoBizFallback(String eventId, ChannelStats channelStats, Exception e) {
        log.warn("링고비즈 API 장애, Fallback 실행: eventId={}, error={}", eventId, e.getMessage());
        channelStats.setTotalCalls(0);
        channelStats.setCompletedCalls(0);
    }

    /**
     * SNS 통계 업데이트
     */
    @CircuitBreaker(name = "sns", fallbackMethod = "snsFallback")
    private void updateSNSStats(String eventId, ChannelStats channelStats) {
        log.debug("SNS API 호출: eventId={}", eventId);
        // 예시 데이터 설정
        channelStats.setLikes(3450);
        channelStats.setComments(890);
        channelStats.setShares(1250);
    }

    /**
     * SNS Fallback
     */
    private void snsFallback(String eventId, ChannelStats channelStats, Exception e) {
        log.warn("SNS API 장애, Fallback 실행: eventId={}, error={}", eventId, e.getMessage());
        channelStats.setLikes(0);
        channelStats.setComments(0);
        channelStats.setShares(0);
    }
}
