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

import com.kt.event.content.biz.domain.Job;
import com.kt.event.content.biz.usecase.out.JobReader;
import com.kt.event.content.biz.usecase.out.JobWriter;
import com.kt.event.content.infra.gateway.entity.JobEntity;
import com.kt.event.content.infra.gateway.repository.JobJpaRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Job 영속성 Gateway
 * JobReader, JobWriter outbound port 구현
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class JobGateway implements JobReader, JobWriter {

    private final JobJpaRepository jobRepository;

    // ========================================
    // JobReader 구현
    // ========================================

    @Override
    @Transactional(readOnly = true)
    public Optional<Job> findById(String jobId) {
        log.debug("Job 조회: jobId={}", jobId);
        return jobRepository.findById(jobId)
                .map(JobEntity::toDomain);
    }

    /**
     * 이벤트별 Job 조회 (추가 메서드)
     */
    @Transactional(readOnly = true)
    public List<Job> findByEventDraftId(Long eventDraftId) {
        log.debug("이벤트별 Job 조회: eventDraftId={}", eventDraftId);
        return jobRepository.findByEventDraftId(eventDraftId).stream()
                .map(JobEntity::toDomain)
                .collect(Collectors.toList());
    }

    /**
     * 최신 Job 조회 (추가 메서드)
     */
    @Transactional(readOnly = true)
    public Optional<Job> findLatestByEventDraftIdAndJobType(Long eventDraftId, String jobType) {
        log.debug("최신 Job 조회: eventDraftId={}, jobType={}", eventDraftId, jobType);
        return jobRepository.findFirstByEventDraftIdAndJobTypeOrderByCreatedAtDesc(eventDraftId, jobType)
                .map(JobEntity::toDomain);
    }

    // ========================================
    // JobWriter 구현
    // ========================================

    @Override
    @Transactional
    public Job save(Job job) {
        log.debug("Job 저장: jobId={}, status={}", job.getId(), job.getStatus());

        JobEntity entity = jobRepository.findById(job.getId())
                .orElseGet(() -> JobEntity.create(
                        job.getId(),
                        job.getEventDraftId(),
                        job.getJobType()
                ));

        // Job 상태 업데이트
        entity.updateStatus(job.getStatus(), job.getProgress());
        if (job.getResultMessage() != null) {
            entity.setResultMessage(job.getResultMessage());
        }
        if (job.getErrorMessage() != null) {
            entity.setErrorMessage(job.getErrorMessage());
        }

        JobEntity saved = jobRepository.save(entity);
        return saved.toDomain();
    }

    /**
     * Job 삭제 (추가 메서드)
     */
    @Transactional
    public void delete(String jobId) {
        log.debug("Job 삭제: jobId={}", jobId);
        jobRepository.deleteById(jobId);
    }
}
