package com.yem.wm.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.*;

/**
 * @Description TODO
 * @Date 2024/2/4 15:32
 * @Created by ZZSLL
 */

public class CalendarUtils
{
    // 将日期部分设为0
    public static Date truncateTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    // 计算日期差异
    public static long calculateDaysDifference(Date targetDate, Date currentDate) {
        long difference = (currentDate.getTime() - targetDate.getTime()) / (1000 * 60 * 60 * 24);
        return Math.abs(difference);
    }

    public static Long calcPayBackCount(Date targetDate) {
        Date currentDate = new Date();
        targetDate = CalendarUtils.truncateTime(targetDate);
        currentDate = CalendarUtils.truncateTime(currentDate);

        long daysDifference = CalendarUtils.calculateDaysDifference(targetDate, currentDate);

        if (targetDate.after(currentDate)) {
            daysDifference = -daysDifference;
            return daysDifference;
        } else {
            return 0L;
        }
    }

    public static Date getFirstDayOfMonth(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate firstDay = localDate.withDayOfMonth(1);
        return Date.from(firstDay.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date getLastDayOfMonth(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate lastDay = localDate.withDayOfMonth(localDate.lengthOfMonth());
        return Date.from(lastDay.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date getFirstDayOfYear(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate firstDay = localDate.withDayOfYear(1);
        return Date.from(firstDay.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date getLastDayOfYear(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate lastDay = localDate.withDayOfYear(localDate.lengthOfYear());
        return Date.from(lastDay.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    public static Date getFirstDayOfWeek(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate firstDayOfWeek = localDate.with(DayOfWeek.MONDAY);
        LocalDateTime startOfDay = firstDayOfWeek.atStartOfDay();
        return Date.from(startOfDay.toInstant(ZoneOffset.UTC));
    }

    public static Date getLastDayOfWeek(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate lastDayOfWeek = localDate.with(DayOfWeek.SUNDAY);
        LocalDateTime endOfDay = lastDayOfWeek.atTime(23, 59, 59, 999000000); // 纳秒设置为999,999,999
        return Date.from(endOfDay.toInstant(ZoneOffset.UTC));
    }

    public static String getMonthName(Date date) {
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM", Locale.ENGLISH);
        return localDate.format(formatter);
    }

    public static Set<String> getMonthsFromStartOfYearToDate(Date fdate) {
        LocalDate date = fdate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        Set<String> monthNames = new HashSet<>();
        for (int monthValue = 1; monthValue <= date.getMonthValue(); monthValue++) {
            Month month = Month.of(monthValue);
            String monthName = month.getDisplayName(TextStyle.FULL, Locale.ENGLISH).toLowerCase();
            monthNames.add(monthName);
        }
        return monthNames;
    }
}
