package gc.mda.kcg.domain.analysis;

import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.OffsetDateTime;
import java.util.List;

/**
 * vessel_analysis_results 직접 조회 서비스.
 * prediction이 write한 분석 결과를 프론트엔드에 제공.
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class VesselAnalysisService {

    private final VesselAnalysisRepository repository;

    /**
     * 분석 결과 목록 조회 (동적 필터).
     */
    public Page<VesselAnalysisResult> getAnalysisResults(
            String mmsi, String zoneCode, String riskLevel, Boolean isDark,
            OffsetDateTime after, Pageable pageable
    ) {
        Specification<VesselAnalysisResult> spec = Specification.where(null);

        if (after != null) {
            spec = spec.and((root, query, cb) -> cb.greaterThan(root.get("analyzedAt"), after));
        }
        if (mmsi != null && !mmsi.isBlank()) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("mmsi"), mmsi));
        }
        if (zoneCode != null && !zoneCode.isBlank()) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("zoneCode"), zoneCode));
        }
        if (riskLevel != null && !riskLevel.isBlank()) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("riskLevel"), riskLevel));
        }
        if (isDark != null && isDark) {
            spec = spec.and((root, query, cb) -> cb.isTrue(root.get("isDark")));
        }

        return repository.findAll(spec, pageable);
    }

    /**
     * 특정 선박 최신 분석 결과.
     */
    public VesselAnalysisResult getLatestByMmsi(String mmsi) {
        return repository.findTopByMmsiOrderByAnalyzedAtDesc(mmsi)
                .orElseThrow(() -> new IllegalArgumentException("ANALYSIS_NOT_FOUND: " + mmsi));
    }

    /**
     * 특정 선박 분석 이력 (시간 범위).
     */
    public List<VesselAnalysisResult> getHistory(String mmsi, int hours) {
        OffsetDateTime after = OffsetDateTime.now().minusHours(hours);
        return repository.findByMmsiAndAnalyzedAtAfterOrderByAnalyzedAtDesc(mmsi, after);
    }

    /**
     * 다크 베셀 목록 (최신 분석, MMSI 중복 제거).
     */
    public Page<VesselAnalysisResult> getDarkVessels(int hours, Pageable pageable) {
        OffsetDateTime after = OffsetDateTime.now().minusHours(hours);
        return repository.findLatestDarkVessels(after, pageable);
    }

    /**
     * 환적 의심 목록 (최신 분석, MMSI 중복 제거).
     */
    public Page<VesselAnalysisResult> getTransshipSuspects(int hours, Pageable pageable) {
        OffsetDateTime after = OffsetDateTime.now().minusHours(hours);
        return repository.findLatestTransshipSuspects(after, pageable);
    }
}
