package com.gcsc.connection.monitoring.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

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

@Service
@Slf4j
@RequiredArgsConstructor
public class PartitionService {

    private final JdbcTemplate jdbcTemplate;

    private static final String TABLE_NAME = "common.snp_api_request_log";
    private static final String PARTITION_PREFIX = "snp_api_request_log_";

    /**
     * 월별 파티션 생성
     */
    public void createPartition(YearMonth yearMonth) {
        String partitionName = TABLE_NAME + "_" + yearMonth.format(DateTimeFormatter.ofPattern("yyyyMM"));
        LocalDate start = yearMonth.atDay(1);
        LocalDate end = yearMonth.plusMonths(1).atDay(1);

        String sql = String.format(
            "CREATE TABLE IF NOT EXISTS %s PARTITION OF %s FOR VALUES FROM ('%s') TO ('%s')",
            partitionName, TABLE_NAME, start, end);

        try {
            jdbcTemplate.execute(sql);
            log.info("파티션 생성 완료: {}", partitionName);
        } catch (Exception e) {
            log.error("파티션 생성 실패: {}", partitionName, e);
        }
    }

    /**
     * 월별 파티션 삭제
     */
    public void dropPartition(YearMonth yearMonth) {
        String partitionName = TABLE_NAME + "_" + yearMonth.format(DateTimeFormatter.ofPattern("yyyyMM"));

        String sql = String.format("DROP TABLE IF EXISTS %s", partitionName);

        try {
            jdbcTemplate.execute(sql);
            log.info("파티션 삭제 완료: {}", partitionName);
        } catch (Exception e) {
            log.error("파티션 삭제 실패: {}", partitionName, e);
        }
    }

    /**
     * 기존 파티션 목록 조회 (API 요청 로그용 - 하위 호환)
     */
    public List<String> getExistingPartitions() {
        return getExistingPartitions(PARTITION_PREFIX);
    }

    /**
     * 기존 파티션 목록 조회 (테이블 접두사 지정)
     */
    public List<String> getExistingPartitions(String tablePrefix) {
        String sql = "SELECT tablename FROM pg_tables WHERE schemaname = 'common' AND tablename LIKE '"
            + tablePrefix + "%' ORDER BY tablename";
        return jdbcTemplate.queryForList(sql, String.class);
    }

    /**
     * 일별 파티션 생성
     */
    public void createDailyPartition(String tableName, LocalDate date) {
        String partitionName = tableName + "_" + date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        LocalDate nextDay = date.plusDays(1);

        String sql = String.format(
            "CREATE TABLE IF NOT EXISTS %s PARTITION OF %s FOR VALUES FROM ('%s') TO ('%s')",
            partitionName, tableName, date, nextDay);

        try {
            jdbcTemplate.execute(sql);
            log.info("일별 파티션 생성 완료: {}", partitionName);
        } catch (Exception e) {
            log.error("일별 파티션 생성 실패: {}", partitionName, e);
        }
    }

    /**
     * 일별 파티션 삭제
     */
    public void dropDailyPartition(String tableName, LocalDate date) {
        String partitionName = tableName + "_" + date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        String sql = String.format("DROP TABLE IF EXISTS %s", partitionName);

        try {
            jdbcTemplate.execute(sql);
            log.info("일별 파티션 삭제 완료: {}", partitionName);
        } catch (Exception e) {
            log.error("일별 파티션 삭제 실패: {}", partitionName, e);
        }
    }
}
