package com.kt.event.content.infra.gateway;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kt.event.content.biz.domain.GeneratedImage;
import com.kt.event.content.biz.usecase.out.RedisAIDataReader;
import com.kt.event.content.biz.usecase.out.RedisImageWriter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Redis Gateway 구현체 (Production 환경용)
 *
 * Local/Test 환경에서는 MockRedisGateway 사용
 */
@Slf4j
@Component
@Profile({"!local", "!test"})
@RequiredArgsConstructor
public class RedisGateway implements RedisAIDataReader, RedisImageWriter {

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper objectMapper;

    private static final String AI_DATA_KEY_PREFIX = "ai:event:";
    private static final String IMAGE_URL_KEY_PREFIX = "image:url:";
    private static final Duration DEFAULT_TTL = Duration.ofHours(24);

    @Override
    public Optional<Map<String, Object>> getAIRecommendation(Long eventDraftId) {
        try {
            String key = AI_DATA_KEY_PREFIX + eventDraftId;
            Object data = redisTemplate.opsForValue().get(key);

            if (data == null) {
                log.warn("AI 이벤트 데이터를 찾을 수 없음: eventDraftId={}", eventDraftId);
                return Optional.empty();
            }

            @SuppressWarnings("unchecked")
            Map<String, Object> aiData = objectMapper.convertValue(data, Map.class);
            return Optional.of(aiData);
        } catch (Exception e) {
            log.error("AI 이벤트 데이터 조회 실패: eventDraftId={}", eventDraftId, e);
            return Optional.empty();
        }
    }

    @Override
    public void cacheImages(Long eventDraftId, List<GeneratedImage> images, long ttlSeconds) {
        try {
            String key = IMAGE_URL_KEY_PREFIX + eventDraftId;

            // 이미지 목록을 캐싱
            redisTemplate.opsForValue().set(key, images, Duration.ofSeconds(ttlSeconds));
            log.info("이미지 목록 캐싱 완료: eventDraftId={}, count={}, ttl={}초",
                    eventDraftId, images.size(), ttlSeconds);
        } catch (Exception e) {
            log.error("이미지 목록 캐싱 실패: eventDraftId={}", eventDraftId, e);
        }
    }

    /**
     * 이미지 URL 캐시 삭제
     */
    public void deleteImageUrl(Long eventDraftId) {
        try {
            String key = IMAGE_URL_KEY_PREFIX + eventDraftId;
            redisTemplate.delete(key);
            log.info("이미지 URL 캐시 삭제: eventDraftId={}", eventDraftId);
        } catch (Exception e) {
            log.error("이미지 URL 캐시 삭제 실패: eventDraftId={}", eventDraftId, e);
        }
    }

    /**
     * AI 이벤트 데이터 캐시 삭제
     */
    public void deleteAIEventData(Long eventDraftId) {
        try {
            String key = AI_DATA_KEY_PREFIX + eventDraftId;
            redisTemplate.delete(key);
            log.info("AI 이벤트 데이터 캐시 삭제: eventDraftId={}", eventDraftId);
        } catch (Exception e) {
            log.error("AI 이벤트 데이터 캐시 삭제 실패: eventDraftId={}", eventDraftId, e);
        }
    }
}
