package com.kt.distribution.repository;

import com.kt.distribution.dto.DistributionStatusResponse;
import com.kt.distribution.entity.DistributionStatus;
import com.kt.distribution.mapper.DistributionStatusMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * 배포 상태 저장소
 *
 * PostgreSQL 데이터베이스를 사용하여 배포 상태를 영구 저장합니다.
 *
 * @author Backend Developer
 * @since 2025-10-24
 */
@Slf4j
@Repository
@RequiredArgsConstructor
public class DistributionStatusRepository {

    private final DistributionStatusJpaRepository jpaRepository;
    private final DistributionStatusMapper mapper;

    /**
     * 배포 상태 저장
     *
     * @param eventId 이벤트 ID
     * @param status 배포 상태 DTO
     */
    @Transactional
    public void save(String eventId, DistributionStatusResponse status) {
        log.debug("Saving distribution status: eventId={}, overallStatus={}", eventId, status.getOverallStatus());

        // 기존 데이터가 있으면 업데이트, 없으면 새로 생성
        Optional<DistributionStatus> existingStatus = jpaRepository.findByEventIdWithChannels(eventId);

        if (existingStatus.isPresent()) {
            // 기존 데이터 업데이트
            DistributionStatus entity = existingStatus.get();
            entity.setOverallStatus(status.getOverallStatus());
            entity.setStartedAt(status.getStartedAt());
            entity.setCompletedAt(status.getCompletedAt());

            // 기존 채널 상태 모두 삭제 후 새로 추가
            entity.getChannels().clear();

            DistributionStatus newEntity = mapper.toEntity(status);
            if (newEntity.getChannels() != null) {
                newEntity.getChannels().forEach(entity::addChannelStatus);
            }

            jpaRepository.save(entity);
        } else {
            // 새로 생성
            DistributionStatus entity = mapper.toEntity(status);
            jpaRepository.save(entity);
        }
    }

    /**
     * 배포 상태 조회
     *
     * @param eventId 이벤트 ID
     * @return 배포 상태 DTO (없으면 Optional.empty())
     */
    @Transactional(readOnly = true)
    public Optional<DistributionStatusResponse> findByEventId(String eventId) {
        log.debug("Finding distribution status: eventId={}", eventId);
        return jpaRepository.findByEventIdWithChannels(eventId)
                .map(mapper::toDto);
    }

    /**
     * 배포 상태 삭제
     *
     * @param eventId 이벤트 ID
     */
    @Transactional
    public void delete(String eventId) {
        log.debug("Deleting distribution status: eventId={}", eventId);
        jpaRepository.deleteByEventId(eventId);
    }

    /**
     * 모든 배포 상태 삭제 (테스트용)
     */
    @Transactional
    public void deleteAll() {
        log.debug("Deleting all distribution statuses");
        jpaRepository.deleteAll();
    }
}
