package org.xyzh.common.utils;

import java.text.DateFormat;
import java.time.Duration;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Instant;
import java.time.ZoneId;
import java.text.ParseException;
/**
 * @description    TimeUtils.java文件描述：时间相关的常用工具方法
 * @filename    TimeUtils.java
 * @author    yslg
 * @copyright yslg
 * @since 2025-11-02
 */

public class TimeUtils {


    /**
     * @description    将时间戳字符串转为指定格式的日期时间字符串
     * @param time    毫秒时间戳字符串
     * @param format    日期格式化对象
     * @return    格式化后的日期时间字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String timeFormat(String time, DateFormat format){
        try {
            Date date = format.parse(time);
            return format.format(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * @description 格式化Date为指定格式字符串
     * @param date Date对象
     * @param pattern 格式化模式，如"yyyy-MM-dd HH:mm:ss"
     * @return String 格式化后的字符串
     */
    public static String format(Date date, String pattern) {
        if (date == null || pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        return ldt.format(formatter);
    }

    /**
     * @description 格式化LocalDate为指定格式字符串
     * @param localDate LocalDate对象
     * @param pattern 格式化模式
     * @return 格式化后的字符串
     */
    public static String format(LocalDate localDate, String pattern) {
        if (localDate == null || pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return localDate.format(formatter);
    }

    /**
     * @description 格式化LocalDateTime为指定格式字符串
     * @param localDateTime LocalDateTime对象
     * @param pattern 格式化模式
     * @return 格式化后的字符串
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        if (localDateTime == null || pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return localDateTime.format(formatter);
    }

    /**
     * @description 格式化时间戳为指定格式字符串
     * @param timestampMillis 毫秒时间戳
     * @param pattern 格式化模式
     * @return 格式化后的字符串
     */
    public static String format(long timestampMillis, String pattern) {
        if (pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        LocalDateTime ldt = Instant.ofEpochMilli(timestampMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
        return ldt.format(formatter);
    }

    /**
     * @description 将字符串按指定格式解析为LocalDateTime
     * @param dateTimeStr 日期时间字符串
     * @param pattern 格式化模式
     * @return LocalDateTime对象，解析失败返回null
     */
    public static LocalDateTime parseToLocalDateTime(String dateTimeStr, String pattern) {
        if (dateTimeStr == null || pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        try {
            return LocalDateTime.parse(dateTimeStr, formatter);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * @description 将字符串按指定格式解析为LocalDate
     * @param dateStr 日期字符串
     * @param pattern 格式化模式
     * @return LocalDate对象，解析失败返回null
     */
    public static LocalDate parseToLocalDate(String dateStr, String pattern) {
        if (dateStr == null || pattern == null) return null;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        try {
            return LocalDate.parse(dateStr, formatter);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * @description 将字符串或Date对象按指定DateTimeFormatter格式化为标准时间字符串（yyyy-MM-dd HH:mm:ss）
     * @param input 可以为String类型的日期、Date对象或LocalDateTime对象
     * @param formatter 指定的DateTimeFormatter
     * @return 标准化时间字符串，无法解析时返回null
     */
    public static String normalizeToDateTimeString(Object input, DateTimeFormatter formatter) {
        if (input == null || formatter == null) return null;
        try {
            if (input instanceof String str) {
                LocalDateTime ldt;
                try {
                    ldt = LocalDateTime.parse(str, formatter);
                } catch (Exception e) {
                    LocalDate ld = LocalDate.parse(str, formatter);
                    ldt = ld.atStartOfDay();
                }
                return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            if (input instanceof Date date) {
                LocalDateTime ldt = dateToLocalDateTime(date);
                return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            if (input instanceof LocalDateTime ldt) {
                return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            if (input instanceof LocalDate ld) {
                return ld.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    /**
     * @description    获取当前时间戳，单位毫秒
     * @return    当前时间戳字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String getCurrentTimestamp() {
        return String.valueOf(System.currentTimeMillis());
    }

    /**
     * @description    获取当前时间戳，单位秒
     * @return    当前时间戳（秒）字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String getCurrentTimestampSeconds() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }

    /**
     * @description    获取当前日期时间，格式：yyyy-MM-dd HH:mm:ss
     * @return    当前日期时间字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String getCurrentDateTime() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * @description    获取当前日期，格式：yyyy-MM-dd
     * @return    当前日期字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String getCurrentDate() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * @description    获取当前时间，格式：HH:mm:ss
     * @return    当前时间字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String getCurrentTime() {
        return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    }

    /**
     * @description    将时间戳（毫秒）转为日期时间字符串，格式：yyyy-MM-dd HH:mm:ss
     * @param timestampMillis    毫秒时间戳
     * @return    日期时间字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String timestampToDateTime(long timestampMillis) {
        return Instant.ofEpochMilli(timestampMillis)
                .atZone(ZoneId.systemDefault())
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * @description    将日期时间字符串（yyyy-MM-dd HH:mm:ss）转为时间戳（毫秒）
     * @param dateTimeStr    日期时间字符串
     * @return    毫秒时间戳
     * @author    yslg
     * @since 2025-11-02
     */
    public static long dateTimeToTimestamp(String dateTimeStr) {
        LocalDateTime ldt = LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return ldt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * @description    获取指定日期加减天数后的日期字符串（yyyy-MM-dd）
     * @param dateStr    原始日期字符串
     * @param days    增加或减少的天数（可为负数）
     * @return    计算后的日期字符串
     * @author    yslg
     * @since 2025-11-02
     */
    public static String plusDays(String dateStr, int days) {
        LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return date.plusDays(days).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    /**
     * @description    获取两个日期之间的天数差
     * @param startDate    开始日期字符串（yyyy-MM-dd）
     * @param endDate    结束日期字符串（yyyy-MM-dd）
     * @return    天数差
     * @author    yslg
     * @since 2025-11-02
     */
    public static long daysBetween(String startDate, String endDate) {
        LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        return Duration.between(start.atStartOfDay(), end.atStartOfDay()).toDays();
    }

    /**
     * @description    判断当前时间是否在指定时间段内
     * @param startTime    开始时间字符串（HH:mm:ss）
     * @param endTime    结束时间字符串（HH:mm:ss）
     * @return    是否在时间段内
     * @author    yslg
     * @since 2025-11-02
     */
    public static Boolean isNowBetween(String startTime, String endTime) {
        LocalTime now = LocalTime.now();
        LocalTime start = LocalTime.parse(startTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
        LocalTime end = LocalTime.parse(endTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
        return !now.isBefore(start) && !now.isAfter(end);
    }

    /**
     * @description    Date转LocalDateTime
     * @param date    java.util.Date对象
     * @return    LocalDateTime对象
     * @author    yslg
     * @since 2025-11-02
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * @description    LocalDateTime转Date
     * @param localDateTime    LocalDateTime对象
     * @return    java.util.Date对象
     * @author    yslg
     * @since 2025-11-02
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

}
