package com.gcsc.connection.monitoring.scheduler;

import com.gcsc.connection.monitoring.service.PartitionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class PartitionManageScheduler {

    private final PartitionService partitionService;

    @Value("${app.partition.enabled:false}")
    private boolean partitionEnabled;

    @Value("${app.partition.advance-months:2}")
    private int advanceMonths;

    @Value("${app.retention.request-log-days:90}")
    private int retentionDays;

    private static final String HEALTH_LOG_TABLE = "common.snp_service_health_log";
    private static final String HEALTH_LOG_PREFIX = "snp_service_health_log_";
    private static final int ADVANCE_DAYS = 7;

    /**
     * 매월 1일 00:00 실행 - 파티션 생성/삭제
     */
    @Scheduled(cron = "0 0 0 1 * *")
    public void managePartitions() {
        if (!partitionEnabled) {
            log.debug("파티션 관리 비활성화 상태");
            return;
        }

        log.info("파티션 관리 시작");
        YearMonth now = YearMonth.now();

        // 미래 파티션 생성
        for (int i = 0; i <= advanceMonths; i++) {
            partitionService.createPartition(now.plusMonths(i));
        }

        // 보관 기간 이전 파티션 삭제 (3개월 전)
        int retentionMonths = retentionDays / 30;
        YearMonth cutoff = now.minusMonths(retentionMonths);

        List<String> existing = partitionService.getExistingPartitions();
        String cutoffStr = "snp_api_request_log_" + cutoff.format(DateTimeFormatter.ofPattern("yyyyMM"));

        for (String partition : existing) {
            if (partition.compareTo(cutoffStr) < 0) {
                YearMonth ym = parsePartitionYearMonth(partition);
                if (ym != null) {
                    partitionService.dropPartition(ym);
                }
            }
        }

        log.info("파티션 관리 완료");
    }

    /**
     * 매일 00:30 실행 - health_log 일별 파티션 관리
     */
    @Scheduled(cron = "0 30 0 * * *")
    public void manageHealthLogPartitions() {
        if (!partitionEnabled) {
            return;
        }

        log.info("Health log 파티션 관리 시작");
        LocalDate today = LocalDate.now();

        // 미래 7일 파티션 생성
        for (int i = 0; i <= ADVANCE_DAYS; i++) {
            partitionService.createDailyPartition(HEALTH_LOG_TABLE, today.plusDays(i));
        }

        // 보관기간 이전 파티션 삭제
        LocalDate cutoff = today.minusDays(retentionDays);
        List<String> existing = partitionService.getExistingPartitions(HEALTH_LOG_PREFIX);

        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd");
        String cutoffStr = HEALTH_LOG_PREFIX + cutoff.format(fmt);

        for (String partition : existing) {
            if (partition.compareTo(cutoffStr) < 0) {
                try {
                    LocalDate partDate = LocalDate.parse(
                        partition.replace(HEALTH_LOG_PREFIX, ""), fmt);
                    partitionService.dropDailyPartition(HEALTH_LOG_TABLE, partDate);
                } catch (Exception e) {
                    log.warn("파티션 날짜 파싱 실패: {}", partition);
                }
            }
        }

        log.info("Health log 파티션 관리 완료");
    }

    private YearMonth parsePartitionYearMonth(String partitionName) {
        try {
            String suffix = partitionName.replace("snp_api_request_log_", "");
            return YearMonth.parse(suffix, DateTimeFormatter.ofPattern("yyyyMM"));
        } catch (Exception e) {
            return null;
        }
    }
}
