package com.sundot.airport.common.utils;

import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.domain.SysAnalysisReportDateRangeDto;
import com.sundot.airport.common.enums.CompareTypeEnum;
import com.sundot.airport.common.exception.ServiceException;

import java.time.LocalDate;
import java.time.Year;

/**
 * 日期范围查询工具类（支持年份、月份、季度指定）
 * 适用于 SysAnalysisReportDateRangeDto 对象生成
 */
public class DateRangeQueryUtils {

    // ==================== 根据年份和月份查询 ====================

    /**
     * 根据指定年份和月份获取该月的起止日期
     */
    public static SysAnalysisReportDateRangeDto getMonthRange(int year, int month, String tag) {
        LocalDate startDate = LocalDate.of(year, month, 1);
        LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());
        String desc = year + "年" + month + "月";
        if (StrUtil.isEmpty(tag)) {
            tag = CompareTypeEnum.CURRENT.getCode();
        }
        return buildDto(startDate, endDate, desc, tag);
    }

    /**
     * 根据指定年份和月份获取上个月的起止日期
     */
    public static SysAnalysisReportDateRangeDto getPreviousMonthRange(int year, int month) {
        LocalDate specifiedDate = LocalDate.of(year, month, 1);
        LocalDate lastMonth = specifiedDate.minusMonths(1);
        String tag = CompareTypeEnum.RING_RATIO.getCode();
        return getMonthRange(lastMonth.getYear(), lastMonth.getMonthValue(), tag);
    }

    /**
     * 根据指定年份和月份获取去年同月的起止日期
     */
    public static SysAnalysisReportDateRangeDto getLastYearSameMonthRange(int year, int month) {
        String tag = CompareTypeEnum.YEAR_ON_YEAR.getCode();
        return getMonthRange(year - 1, month, tag);
    }

    // ==================== 根据年份和季度查询 ====================

    /**
     * 根据指定年份和季度获取该季度的起止日期
     * 季度划分：Q1(1-3月), Q2(4-6月), Q3(7-9月), Q4(10-12月)
     */
    public static SysAnalysisReportDateRangeDto getQuarterRange(int year, int quarter, String tag) {
        LocalDate startDate, endDate;

        switch (quarter) {
            case 1:
                startDate = LocalDate.of(year, 1, 1);
                endDate = LocalDate.of(year, 3, 31);
                break;
            case 2:
                startDate = LocalDate.of(year, 4, 1);
                endDate = LocalDate.of(year, 6, 30);
                break;
            case 3:
                startDate = LocalDate.of(year, 7, 1);
                endDate = LocalDate.of(year, 9, 30);
                break;
            case 4:
                startDate = LocalDate.of(year, 10, 1);
                endDate = LocalDate.of(year, 12, 31);
                break;
            default:
                throw new ServiceException("无效的季度: " + quarter + "，季度范围应为1-4");
        }

        String desc = year + "年第" + quarter + "季度";
        if (StrUtil.isEmpty(tag)) {
            tag = CompareTypeEnum.CURRENT.getCode();
        }
        return buildDto(startDate, endDate, desc, tag);
    }

    /**
     * 根据指定年份和季度获取上一个季度的起止日期
     */
    public static SysAnalysisReportDateRangeDto getPreviousQuarterRange(int year, int quarter) {
        int previousQuarter = quarter - 1;
        int targetYear = year;

        if (previousQuarter == 0) {
            previousQuarter = 4;
            targetYear = year - 1;
        }

        String tag = CompareTypeEnum.RING_RATIO.getCode();
        return getQuarterRange(targetYear, previousQuarter, tag);
    }

    /**
     * 根据指定年份和季度获取去年同季度的起止日期
     */
    public static SysAnalysisReportDateRangeDto getLastYearSameQuarterRange(int year, int quarter) {
        String tag = CompareTypeEnum.YEAR_ON_YEAR.getCode();
        return getQuarterRange(year - 1, quarter, tag);
    }

    // ==================== 根据年份查询 ====================

    /**
     * 根据指定年份获取该年度的起止日期
     */
    public static SysAnalysisReportDateRangeDto getYearRange(int year, String tag) {
        LocalDate startDate = LocalDate.of(year, 1, 1);
        LocalDate endDate = LocalDate.of(year, 12, 31);
        String desc = year + "年";

        if (StrUtil.isEmpty(tag)) {
            tag = CompareTypeEnum.CURRENT.getCode();
        }
        return buildDto(startDate, endDate, desc, tag);
    }

    /**
     * 根据指定年份获取上一年度的起止日期
     */
    public static SysAnalysisReportDateRangeDto getPreviousYearRange(int year) {
        String tag = CompareTypeEnum.YEAR_ON_YEAR.getCode();
        return getYearRange(year - 1, tag);
    }

    // ==================== 便捷方法（基于当前日期）====================

    /**
     * 获取当前月份范围（基于当前日期）
     */
    public static SysAnalysisReportDateRangeDto getCurrentMonthRange() {
        LocalDate today = LocalDate.now();
        String tag = CompareTypeEnum.CURRENT.getCode();
        return getMonthRange(today.getYear(), today.getMonthValue(), tag);
    }

    /**
     * 获取当前季度范围（基于当前日期）
     */
    public static SysAnalysisReportDateRangeDto getCurrentQuarterRange() {
        LocalDate today = LocalDate.now();
        int quarter = (today.getMonthValue() - 1) / 3 + 1;
        String tag = CompareTypeEnum.CURRENT.getCode();
        return getQuarterRange(today.getYear(), quarter, tag);
    }

    /**
     * 获取当前年度范围（基于当前日期）
     */
    public static SysAnalysisReportDateRangeDto getCurrentYearRange() {
        String tag = CompareTypeEnum.CURRENT.getCode();
        return getYearRange(Year.now().getValue(), tag);
    }

    // ==================== 辅助方法 ====================

    /**
     * 构建 SysAnalysisReportDateRangeDto 对象
     */
    private static SysAnalysisReportDateRangeDto buildDto(LocalDate start, LocalDate end, String desc, String tag) {
        SysAnalysisReportDateRangeDto dto = new SysAnalysisReportDateRangeDto();
        dto.setStartDate(java.sql.Date.valueOf(start));
        dto.setEndDate(java.sql.Date.valueOf(end));
        dto.setDesc(desc);
        dto.setTag(tag);
        dto.setTagDesc(CompareTypeEnum.getByCode(tag).getDesc());
        return dto;
    }

    /**
     * 根据月份获取对应的季度
     */
    public static int getQuarterByMonth(int month) {
        if (month < 1 || month > 12) {
            throw new IllegalArgumentException("月份必须在1-12之间");
        }
        return (month - 1) / 3 + 1;
    }

    /**
     * 验证季度是否有效
     */
    public static boolean isValidQuarter(int quarter) {
        return quarter >= 1 && quarter <= 4;
    }

    /**
     * 验证月份是否有效
     */
    public static boolean isValidMonth(int month) {
        return month >= 1 && month <= 12;
    }

}
