package org.example.Utils;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * ==============================================================================
 * 功能描述：DateTimeUtil
 * ==============================================================================
 */
public class DateTimeUtil {

    private static final Date JAN_1ST_1970 = new Date(0); // 1970-01-01 00:00:00 UTC

    /**
     * 获取当前时间的毫秒数（UTC时间）
     */
    public static long currentTimeMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 将毫秒数转换为日期时间
     */
    public static Date timeSpanToDate(long timespan) {
        return new Date(timespan);
    }

    /**
     * 获取网络日期时间（从URL响应头的Date字段）
     */
    public static String getNetDateTime(String url) {
        if (url == null || url.isEmpty()) {
            url = "https://www.baidu.com";
        }

        HttpURLConnection connection = null;
        try {
            URL urlObj = new URL(url);
            connection = (HttpURLConnection) urlObj.openConnection();
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(3000);
            connection.setRequestMethod("HEAD");

            // 获取响应头中的Date字段
            return connection.getHeaderField("Date");
        } catch (IOException e) {
            return "";
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    // NIST时间服务器相关配置
    private static final int THRESHOLD_SECONDS = 15;
    private static final String[] SERVERS = {
            "129.6.15.29",
            "132.163.4.101",
            "132.163.4.102",
            "132.163.4.103",
            "128.138.140.44",
            "192.43.244.18",
            "131.107.1.10",
            "66.243.43.21",
            "216.200.93.8",
            "208.184.49.9",
            "207.126.98.204",
            "205.188.185.33"
    };

    public static String lastHost = "";
    public static Date lastSysTime;

    /**
     * 获取网络时间（NIST服务器）
     */
    public static Date getNetTime() {
        lastHost = "";
        Date result = null;

        for (String host : SERVERS) {
            result = getNISTTime(host);
            if (result != null) {
                lastHost = host;
                break;
            }
        }

        // 如果所有服务器都失败，返回系统UTC时间
        if (result == null) {
            result = new Date(System.currentTimeMillis());
        }

        return result;
    }

    /**
     * 从NIST服务器获取时间
     */
    private static Date getNISTTime(String host) {
        Socket socket = null;
        BufferedReader reader = null;

        try {
            socket = new Socket(host, 13);
            socket.setSoTimeout(3000);
            lastSysTime = new Date(System.currentTimeMillis()); // 记录系统时间

            // 读取服务器响应
            reader = new BufferedReader(
                    new InputStreamReader(socket.getInputStream(), StandardCharsets.US_ASCII)
            );
            String timeStr = reader.readLine();

            if (timeStr == null || timeStr.isEmpty()) {
                return null;
            }

            // 验证NIST时间格式
            if (timeStr.length() < 38 || !timeStr.substring(38, 47).equals("UTC(NIST)")) {
                return null;
            }
            if (timeStr.charAt(30) != '0') {
                return null; // 服务器状态非最佳
            }

            // 解析时间字符串
            int jd = Integer.parseInt(timeStr.substring(1, 6).trim());
            int yr = Integer.parseInt(timeStr.substring(7, 9).trim());
            int mo = Integer.parseInt(timeStr.substring(10, 12).trim());
            int dy = Integer.parseInt(timeStr.substring(13, 15).trim());
            int hr = Integer.parseInt(timeStr.substring(16, 18).trim());
            int mm = Integer.parseInt(timeStr.substring(19, 21).trim());
            int sc = Integer.parseInt(timeStr.substring(22, 24).trim());

            // 处理年份（NIST时间格式中的年份是两位数）
            if (jd > 51544) {
                yr += 2000;
            } else {
                yr += 1900;
            }

            // 构建日期对象（NIST返回的是UTC时间）
            Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
            calendar.set(yr, mo - 1, dy, hr, mm, sc);
            calendar.set(Calendar.MILLISECOND, 0);
            return calendar.getTime();

        } catch (IOException | NumberFormatException e) {
            return null;
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // 忽略关闭异常
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // 忽略关闭异常
                }
            }
        }
    }

    /**
     * 计算两个时间的差值（天时分秒）
     */
    public static String getDateDiff(Date startTime, Date endTime) {
        if (startTime == null || endTime == null) {
            return "";
        }

        long diffMs = endTime.getTime() - startTime.getTime();
        if (diffMs <= 0) {
            return "";
        }

        StringBuilder result = new StringBuilder();

        // 计算天数
        long days = diffMs / (24 * 3600 * 1000);
        if (days > 0) {
            result.append(days).append("天");
        }

        // 剩余毫秒数
        long leave1 = diffMs % (24 * 3600 * 1000);
        // 计算小时数
        long hours = leave1 / (3600 * 1000);
        if (hours > 0) {
            result.append(hours).append("小时");
        }

        // 剩余毫秒数
        long leave2 = leave1 % (3600 * 1000);
        // 计算分钟数
        long minutes = leave2 / (60 * 1000);
        if (minutes > 0) {
            result.append(minutes).append("分钟");
        }

        // 剩余毫秒数
        long leave3 = leave2 % (60 * 1000);
        // 计算秒数
        long seconds = Math.round(leave3 / 1000.0);
        if (seconds > 0) {
            result.append(seconds).append("秒");
        }

        return result.toString();
    }

    /**
     * 延迟执行任务（类似JavaScript的setTimeout）
     *
     * @param callback 回调任务
     * @param delay    延迟时间（毫秒）
     * @return 定时任务调度器（用于取消任务）
     */
    public static ScheduledExecutorService setTimeOut(Runnable callback, int delay) {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.schedule(() -> {
            try {
                callback.run();
            } finally {
                scheduler.shutdown();
            }
        }, delay, TimeUnit.MILLISECONDS);
        return scheduler;
    }

    /**
     * 周期性执行任务（类似JavaScript的setInterval）
     *
     * @param callback 回调任务
     * @param delay    间隔时间（毫秒）
     * @return 定时任务调度器（用于取消任务）
     */
    public static ScheduledExecutorService setInterval(Runnable callback, int delay) {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(callback, 0, delay, TimeUnit.MILLISECONDS);
        return scheduler;
    }

    /**
     * 取消周期性任务
     */
    public static void clearInterval(ScheduledExecutorService scheduler) {
        if (scheduler != null) {
            scheduler.shutdown();
        }
    }
}
