package com.ecep.contract;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyDateTimeUtils {
    /**
     * 日期 yyyy-MM-dd 的正则表达式
     */
    public static final String REGEX_DATE = "\\d{4}-\\d{2}-\\d{2}";
    /**
     * 默认日期的格式
     */
    public static final String DEFAULT_DATE_FORMAT_PATTERN = "yyyy-MM-dd";
    /**
     * 默认时间的格式
     */
    public static final String DEFAULT_TIME_FORMAT_PATTERN = "HH:mm:ss";
    /**
     * 默认日期时间的格式
     */
    public static final String DEFAULT_DATETIME_FORMAT_PATTERN = DEFAULT_DATE_FORMAT_PATTERN + " "
            + DEFAULT_TIME_FORMAT_PATTERN;

    /**
     * 判断 verifyDate 是否在 startDate 和 endDate 之间，
     * 当 graceDays 大于 0 时，startDate 往前移 graceDays 天，endDate 往后移 graceDays 天
     *
     * @param verifyDate 判断的日期
     * @param startDate  起始日期（包含）
     * @param endDate    截至日期（包含）
     * @param graceDays  宽限日期
     * @return 在 startDate 和 endDate 之间返回true，否则返回false
     */
    public static boolean dateValidFilter(LocalDate verifyDate, LocalDate startDate, LocalDate endDate, int graceDays) {
        // 截至日期 endDate 在 验证日期 verifyDate 前, 表示 verifyDate 已经超出 endDate 范围
        if (endDate.isBefore(verifyDate)) {
            // 如果允许宽限期
            if (graceDays > 0) {
                // 截至日期宽限至
                LocalDate graceDate = endDate.plusDays(graceDays);
                if (graceDate.isBefore(verifyDate)) {
                    return false;
                }
            } else {
                return false;
            }
        }
        // 起始日期 startDate 在 验证日期 verifyDate 后, 表示 verifyDate 已经超出 startDate 范围
        if (startDate.isAfter(verifyDate)) {
            // 如果允许宽限期
            if (graceDays > 0) {
                LocalDate graceDate = startDate.minusDays(graceDays);
                if (graceDate.isAfter(verifyDate)) {
                    return false;
                }
            } else {
                return false;
            }
        }

        return true;
    }

    /**
     * 格式化日期，默认格式 yyyy-MM-dd
     *
     * @param date 要格式化的日期对象
     * @return 格式化后的日期字符串
     */
    public static String format(LocalDate date) {
        return format(date, DEFAULT_DATE_FORMAT_PATTERN);
    }

    /**
     * 格式化日期，使用指定的格式
     *
     * @param date    要格式化的日期对象
     * @param pattern 日期格式
     * @return 格式化后的日期字符串
     */
    public static String format(LocalDate date, String pattern) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
        return date.format(fmt);
    }

    /**
     * 格式化时间，默认格式 HH:mm:ss
     *
     * @param dateTime 要格式化的时间对象
     * @return 格式化后的时间字符串
     */
    public static String format(LocalDateTime dateTime) {
        return format(dateTime, DEFAULT_DATETIME_FORMAT_PATTERN);
    }

    /**
     * 格式化时间，使用指定的格式
     *
     * @param dateTime 要格式化的时间对象
     * @param pattern  时间格式
     * @return 格式化后的时间字符串
     */
    public static String format(LocalDateTime dateTime, String pattern) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
        return dateTime.format(fmt);
    }

    /**
     * 格式化时间，默认格式 HH:mm:ss
     *
     * @param time 要格式化的时间对象
     * @return 格式化后的时间字符串
     */
    public static String format(LocalTime time) {
        return format(time, DEFAULT_TIME_FORMAT_PATTERN);
    }

    /**
     * 格式化时间，使用指定的格式
     *
     * @param time    要格式化的时间对象
     * @param pattern 时间格式
     * @return 格式化后的时间字符串
     */
    public static String format(LocalTime time, String pattern) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
        return time.format(fmt);
    }

    /**
     * 从字符串中提取日期, 匹配日期未 yyyy-MM-dd
     *
     * @param string 要日期提取的字符串
     * @return 提取的日期, 如果没有匹配到则返回null
     */
    public static LocalDate pickLocalDate(String string) {
        return pickLocalDate(string, REGEX_DATE);
    }

    /**
     * 从字符串中提取日期, 使用正则表达式匹配，如果字符串中有多个匹配，只提取第一个
     *
     * @param string 要日期提取的字符串
     * @param regex  日期的正则表达式
     * @return 提取的日期, 如果没有匹配到则返回null
     */
    public static LocalDate pickLocalDate(String string, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(string);
        while (matcher.find()) {
            String date = matcher.group();
            try {
                return LocalDate.parse(date);
            } catch (Exception ignored) {
            }
        }
        return null;
    }

    public static String format(long startTime) {
        return format(new Date(startTime));

    }

    public static String format(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT_PATTERN);
        return sdf.format(date);
    }
}
