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

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kt.event.eventservice.application.dto.kafka.AIEventGenerationJobMessage;
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;

/**
 * AI 이벤트 생성 작업 메시지 구독 Consumer
 *
 * ai-event-generation-job 토픽의 메시지를 구독하여 처리합니다.
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AIJobKafkaConsumer {

    private final ObjectMapper objectMapper;

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

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

            log.info("AI 작업 메시지 파싱 완료 - JobId: {}, UserId: {}, Status: {}",
                message.getJobId(), message.getUserId(), message.getStatus());

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

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

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

    /**
     * AI 이벤트 생성 작업 처리
     *
     * @param message AI 이벤트 생성 작업 메시지
     */
    private void processAIEventGenerationJob(AIEventGenerationJobMessage message) {
        switch (message.getStatus()) {
            case "COMPLETED":
                log.info("AI 작업 완료 처리 - JobId: {}, UserId: {}",
                    message.getJobId(), message.getUserId());
                // TODO: AI 추천 결과를 캐시 또는 DB에 저장
                // TODO: 사용자에게 알림 전송
                break;

            case "FAILED":
                log.error("AI 작업 실패 처리 - JobId: {}, Error: {}",
                    message.getJobId(), message.getErrorMessage());
                // TODO: 실패 로그 저장 및 사용자 알림
                break;

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

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