package com.nailart.utils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 日期处理工具类，基于Java 8+的java.time包
 */
public class DateUtils {
    // 默认日期格式
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    // 默认日期时间格式
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    // 默认时间格式
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    // 日期格式化器
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
    // 日期时间格式化器
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATETIME_FORMAT);
    // 时间格式化器
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT);

    /**
     * 获取当前日期（yyyy-MM-dd）
     * @return 当前日期字符串
     */
    public static String getCurrentDate() {
        return LocalDate.now().format(DATE_FORMATTER);
    }

    /**
     * 获取当前日期时间（yyyy-MM-dd HH:mm:ss）
     * @return 当前日期时间字符串
     */
    public static String getCurrentDateTime() {
        return LocalDateTime.now().format(DATETIME_FORMATTER);
    }

    /**
     * 获取当前时间（HH:mm:ss）
     * @return 当前时间字符串
     */
    public static String getCurrentTime() {
        return LocalTime.now().format(TIME_FORMATTER);
    }

    /**
     * 日期转字符串
     * @param date 日期
     * @param pattern 格式模式
     * @return 格式化后的日期字符串
     */
    public static String formatDate(LocalDate date, String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 日期时间转字符串
     * @param dateTime 日期时间
     * @param pattern 格式模式
     * @return 格式化后的日期时间字符串
     */
    public static String formatDateTime(LocalDateTime dateTime, String pattern) {
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 字符串转日期
     * @param dateStr 日期字符串
     * @param pattern 格式模式
     * @return 解析后的LocalDate
     */
    public static LocalDate parseDate(String dateStr, String pattern) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 字符串转日期时间
     * @param dateTimeStr 日期时间字符串
     * @param pattern 格式模式
     * @return 解析后的LocalDateTime
     */
    public static LocalDateTime parseDateTime(String dateTimeStr, String pattern) {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 计算两个日期之间的天数差
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 天数差（正数表示结束日期晚于开始日期）
     */
    public static long daysBetween(LocalDate startDate, LocalDate endDate) {
        return ChronoUnit.DAYS.between(startDate, endDate);
    }

    /**
     * 计算两个日期时间之间的小时差
     * @param startDateTime 开始日期时间
     * @param endDateTime 结束日期时间
     * @return 小时差
     */
    public static long hoursBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        return ChronoUnit.HOURS.between(startDateTime, endDateTime);
    }

    /**
     * 计算两个日期时间之间的分钟差
     * @param startDateTime 开始日期时间
     * @param endDateTime 结束日期时间
     * @return 分钟差
     */
    public static long minutesBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        return ChronoUnit.MINUTES.between(startDateTime, endDateTime);
    }

    /**
     * 在指定日期上增加/减少天数
     * @param date 基准日期
     * @param days 增加(正数)/减少(负数)的天数
     * @return 计算后的日期
     */
    public static LocalDate plusDays(LocalDate date, int days) {
        return date.plusDays(days);
    }

    /**
     * 在指定日期时间上增加/减少小时
     * @param dateTime 基准日期时间
     * @param hours 增加(正数)/减少(负数)的小时
     * @return 计算后的日期时间
     */
    public static LocalDateTime plusHours(LocalDateTime dateTime, int hours) {
        return dateTime.plusHours(hours);
    }

    /**
     * 在指定日期时间上增加/减少分钟
     * @param dateTime 基准日期时间
     * @param minutes 增加(正数)/减少(负数)的分钟
     * @return 计算后的日期时间
     */
    public static LocalDateTime plusMinutes(LocalDateTime dateTime, int minutes) {
        return dateTime.plusMinutes(minutes);
    }

    /**
     * Date转LocalDateTime
     * @param date Date对象
     * @return LocalDateTime对象
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * LocalDateTime转Date
     * @param dateTime LocalDateTime对象
     * @return Date对象
     */
    public static Date toDate(LocalDateTime dateTime) {
        return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取一天的开始时间（00:00:00）
     * @param date 日期
     * @return 当天开始时间的LocalDateTime
     */
    public static LocalDateTime getStartOfDay(LocalDate date) {
        return date.atStartOfDay();
    }

    /**
     * 获取一天的结束时间（23:59:59）
     * @param date 日期
     * @return 当天结束时间的LocalDateTime
     */
    public static LocalDateTime getEndOfDay(LocalDate date) {
        return LocalDateTime.of(date, LocalTime.MAX);
    }

    /**
     * 判断日期是否在范围内
     * @param targetDate 目标日期
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return true-在范围内；false-不在范围内
     */
    public static boolean isDateInRange(LocalDate targetDate, LocalDate startDate, LocalDate endDate) {
        return !targetDate.isBefore(startDate) && !targetDate.isAfter(endDate);
    }
}
