package com.kt.event.eventservice.infrastructure.kafka;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kt.event.eventservice.application.dto.kafka.ImageGenerationJobMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

/**
 * 이미지 생성 작업 메시지 구독 Consumer
 *
 * image-generation-job 토픽의 메시지를 구독하여 처리합니다.
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ImageJobKafkaConsumer {

    private final ObjectMapper objectMapper;

    /**
     * 이미지 생성 작업 메시지 수신 처리
     *
     * @param payload 메시지 페이로드 (JSON)
     * @param partition 파티션 번호
     * @param offset 오프셋
     * @param acknowledgment 수동 커밋용 Acknowledgment
     */
    @KafkaListener(
        topics = "${app.kafka.topics.image-generation-job}",
        groupId = "${spring.kafka.consumer.group-id}",
        containerFactory = "kafkaListenerContainerFactory"
    )
    public void consumeImageGenerationJob(
        @Payload String payload,
        @Header(KafkaHeaders.RECEIVED_PARTITION) int partition,
        @Header(KafkaHeaders.OFFSET) long offset,
        Acknowledgment acknowledgment
    ) {
        try {
            log.info("이미지 생성 작업 메시지 수신 - Partition: {}, Offset: {}", partition, offset);

            // JSON을 객체로 변환
            ImageGenerationJobMessage message = objectMapper.readValue(
                payload,
                ImageGenerationJobMessage.class
            );

            log.info("이미지 작업 메시지 파싱 완료 - JobId: {}, EventId: {}, Status: {}",
                message.getJobId(), message.getEventId(), message.getStatus());

            // 메시지 처리 로직
            processImageGenerationJob(message);

            // 수동 커밋
            acknowledgment.acknowledge();
            log.info("이미지 생성 작업 메시지 처리 완료 - JobId: {}", message.getJobId());

        } catch (Exception e) {
            log.error("이미지 생성 작업 메시지 처리 중 오류 발생 - Partition: {}, Offset: {}, Error: {}",
                partition, offset, e.getMessage(), e);
            // 에러 발생 시에도 커밋 (재처리 방지, DLQ 사용 권장)
            acknowledgment.acknowledge();
        }
    }

    /**
     * 이미지 생성 작업 처리
     *
     * @param message 이미지 생성 작업 메시지
     */
    private void processImageGenerationJob(ImageGenerationJobMessage message) {
        switch (message.getStatus()) {
            case "COMPLETED":
                log.info("이미지 작업 완료 처리 - JobId: {}, EventId: {}, ImageURL: {}",
                    message.getJobId(), message.getEventId(), message.getImageUrl());
                // TODO: 생성된 이미지 URL을 캐시 또는 DB에 저장
                // TODO: 이벤트 엔티티에 이미지 URL 업데이트
                // TODO: 사용자에게 알림 전송
                break;

            case "FAILED":
                log.error("이미지 작업 실패 처리 - JobId: {}, EventId: {}, Error: {}",
                    message.getJobId(), message.getEventId(), message.getErrorMessage());
                // TODO: 실패 로그 저장 및 사용자 알림
                // TODO: 재시도 로직 또는 기본 이미지 사용
                break;

            case "PROCESSING":
                log.info("이미지 작업 진행 중 - JobId: {}, EventId: {}",
                    message.getJobId(), message.getEventId());
                // TODO: 작업 상태 업데이트
                break;

            default:
                log.warn("알 수 없는 작업 상태 - JobId: {}, EventId: {}, Status: {}",
                    message.getJobId(), message.getEventId(), message.getStatus());
        }
    }
}
