package com.tongran.common.core.utils;

import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;

@Component
public class TableSubUtil {

    // 日期格式
    private static final String YEAR_MONTH_FORMAT = "yyyy_MM";
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";


    /**
     * 根据创建时间获取表名（过滤不存在的表）
     */
    public static String getExistingTableName(Date createTime, String prefix) {
        String tableName = getTableName(createTime, prefix);
        return tableExists(tableName) ? tableName : null;
    }

    /**
     * 获取时间范围内涉及的所有存在的表名
     */
    public static Set<String> getExistingTableNamesBetween(String startTime, String endTime, String prefix) {
        Set<String> allTables = getTableNamesBetween(startTime, endTime, prefix);
        Set<String> existingTables = new LinkedHashSet<>();

        for (String table : allTables) {
            if (tableExists(table)) {
                existingTables.add(table);
            }
        }
        return existingTables;
    }

    /**
     * 根据创建时间获取表名（原始方法）
     */
    public static String getTableName(Date createTime, String prefix) {
        if (createTime == null) {
            throw new IllegalArgumentException("创建时间不能为null");
        }

        SimpleDateFormat yearMonthFormat = new SimpleDateFormat(YEAR_MONTH_FORMAT);
        String yearMonth = yearMonthFormat.format(createTime);

        SimpleDateFormat dayFormat = new SimpleDateFormat("dd");
        int day = Integer.parseInt(dayFormat.format(createTime));

        return String.format("%s_%s_%s", prefix, yearMonth, getDayRange(day));
    }

    /**
     * 获取时间范围内涉及的所有表名（原始方法）
     */
    public static Set<String> getTableNamesBetween(String startTime, String endTime, String prefix) {
        Date start = parseDateTime(startTime);
        Date end = parseDateTime(endTime);
        validateTimeRange(start, end);

        Set<String> tableNames = new LinkedHashSet<>();
        Calendar current = Calendar.getInstance();
        current.setTime(start);
        current.set(Calendar.HOUR_OF_DAY, 0);
        current.set(Calendar.MINUTE, 0);
        current.set(Calendar.SECOND, 0);
        current.set(Calendar.MILLISECOND, 0);

        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end);

        while (!current.after(endCal)) {
            tableNames.add(getTableName(current.getTime(), prefix));
            current.add(Calendar.DAY_OF_MONTH, 1);
        }

        return tableNames;
    }

    /**
     * 检查表是否存在
     */
    private static boolean tableExists(String tableName) {
        try {
            // 直接从SpringUtils获取数据源
            javax.sql.DataSource dataSource = SpringUtils.getBean(javax.sql.DataSource.class);

            try (Connection conn = dataSource.getConnection()) {
                DatabaseMetaData metaData = conn.getMetaData();
                try (ResultSet rs = metaData.getTables(conn.getCatalog(), null, tableName, new String[]{"TABLE"})) {
                    return rs.next();
                }
            }
        } catch (Exception e) {
            System.err.println("检查表是否存在失败: " + tableName + ", error: " + e.getMessage());
            return false;
        }
    }

    // 以下为原有辅助方法保持不变
    private static Date parseDateTime(String dateTimeStr) {
        if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
            throw new IllegalArgumentException("时间字符串不能为空");
        }
        try {
            SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT);
            return format.parse(dateTimeStr);
        } catch (ParseException e) {
            throw new IllegalArgumentException("时间格式必须为: yyyy-MM-dd HH:mm:ss", e);
        }
    }

    private static String getDayRange(int day) {
        if (day < 1 || day > 31) {
            throw new IllegalArgumentException("日期必须在1-31之间");
        }
        if (day <= 10) return "1_10";
        if (day <= 20) return "11_20";
        return "21_31";
    }

    private static void validateTimeRange(Date start, Date end) {
        if (start == null || end == null) {
            throw new IllegalArgumentException("时间范围参数不能为null");
        }
        if (start.after(end)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }
    }
}