package com.red.circle.console.infra.database.util;


import java.sql.Timestamp;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * LocalDateTime工具类.
 *
 * @author pengliang
 * @since 2019/7/11 13:47
 */
public interface LocalDateUtils {

  /**
   * 获取上周一.
   *
   * @return ignore
   */
  static LocalDate nowLastWeekMonday() {
    return LocalDate.now().minusWeeks(1).minusDays(LocalDate.now().getDayOfWeek().getValue() - 1);
  }

  /**
   * 获取当前时间的上周日.
   *
   * @return ignore
   */
  static LocalDate nowLastWeekSunday() {
    return LocalDate.now().minusWeeks(1).minusDays(LocalDate.now().getDayOfWeek().getValue() - 7);
  }

  /**
   * 获取本周一.
   */
  static LocalDate nowWeekMonday() {
    return LocalDate.now().minusDays(LocalDate.now().getDayOfWeek().getValue() - 1);
  }

  /**
   * 获取本周一 转 int.
   */
  static Integer nowWeekMondayToInteger() {
    return Integer.valueOf(format(nowWeekMonday(), "yyyyMMdd"));
  }

  /**
   * 获取本周一.
   */
  static String nowWeekMondayToStr() {
    return format(nowWeekMonday(), "yyyyMMdd");
  }

  /**
   * 获取本周二.
   *
   * @return ignore
   */
  static LocalDate nowTuesday() {
    return LocalDate.now().minusDays(LocalDate.now().getDayOfWeek().getValue() - 2);
  }


  /**
   * 获取本周三,转int.
   *
   * @return ignore
   */
  static Integer nowWednesdayToInteger() {
    return Integer.valueOf(format(nowWednesday(), "yyyyMMdd"));
  }

  /**
   * 获取本周三.
   *
   * @return ignore
   */
  static LocalDate nowWednesday() {
    return LocalDate.now().minusDays(LocalDate.now().getDayOfWeek().getValue() - 3);
  }

  /**
   * 一周的最后一天.
   */
  static LocalDate nowLastDayOfWeek() {
    return LocalDate.now().with(DayOfWeek.SUNDAY);
  }

  /**
   * 获取本月号码.
   */
  static Integer nowMonthToInt() {
    return Integer.valueOf(format(LocalDate.now(), "yyyyMM"));
  }

  /**
   * 获取本月一号.
   */
  static LocalDate nowFirstDayOfMonth() {
    return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
  }

  /**
   * 获取本月一号,转数值.
   */
  static Integer nowFirstDayOfMonthToInteger() {
    return Integer.valueOf(format(nowFirstDayOfMonth(), "yyyyMMdd"));
  }

  /**
   * 获取本月,转数值.
   */
  static Integer nowThisMonthToInteger() {
    return Integer.valueOf(format(LocalDate.now(), "yyyyMM"));
  }

  /**
   * 获取本月最后一天.
   */
  static LocalDate nowLastDayOfMonth() {
    return getLastDayOfMonth(LocalDate.now());
  }

  /**
   * 获取本月最后一天 - int
   */
  static Integer nowLastDayOfMonthToInteger() {
    return Integer.valueOf(format(nowLastDayOfMonth(), "yyyyMMdd"));
  }

  /**
   * 本月余天数.
   */
  static Integer nowMonthRemainDays() {
    return nowLastDayOfMonth().getDayOfMonth() - LocalDate.now().getDayOfMonth();
  }

  /**
   * 获取指定日期最后一天.
   */
  static LocalDate getLastDayOfMonth(LocalDate date) {
    return date.with(TemporalAdjusters.lastDayOfMonth());
  }

  /**
   * 将string转换为LocalDate.
   *
   * @param date    日期
   * @param pattern 格式
   * @return LocalDate
   */
  static LocalDate convert(String date, String pattern) {
    return LocalDate.parse(date, DateTimeFormatter.ofPattern(pattern));
  }

  /**
   * 将timestamp转换为LocalDate.
   *
   * @param time 时间戳
   * @return LocalDate
   */
  static LocalDate convert(Long time) {
    return Instant.ofEpochMilli(time).atZone(DateZoneOffset.DEFAULT_ZONE_OFF_SET).toLocalDate();
  }

  /**
   * 将LocalDate转换为timestamp.
   *
   * @param localDate ingore
   * @return LocalDate
   */
  static Timestamp convertTimestamp(LocalDate localDate) {
    return new Timestamp(toEpochMilli(localDate));
  }

  /**
   * 获取毫秒.
   *
   * @param localDate 待转换 localDate
   * @return 毫秒
   */
  static long toEpochMilli(LocalDate localDate) {
    return localDate.atStartOfDay(DateZoneOffset.DEFAULT_ZONE_OFF_SET).toInstant().toEpochMilli();
  }

  /**
   * 在当前时间基础上追加指定天数转换为timestamp.
   *
   * @param day 天
   * @return setTimestamp
   */
  static Timestamp nowPlusDaysToTimestamp(long day) {
    return new Timestamp(
        LocalDate.now()
            .plusDays(day)
            .atStartOfDay(DateZoneOffset.DEFAULT_ZONE_OFF_SET).toInstant().toEpochMilli()
    );
  }

  /**
   * 在当前时间基础上减指定天数转换为timestamp.
   *
   * @param day 天
   * @return setTimestamp
   */
  static Timestamp nowMinusDaysToTimestamp(long day) {
    return new Timestamp(
        LocalDate.now()
            .minusDays(day)
            .atStartOfDay(DateZoneOffset.DEFAULT_ZONE_OFF_SET).toInstant().toEpochMilli()
    );
  }

  /**
   * 获取本周二,转int.
   *
   * @return ignore
   */
  static Integer nowTuesdayToInteger() {
    return Integer.valueOf(format(nowTuesday(), "yyyyMMdd"));
  }

  /**
   * 时间转int.
   *
   * @return ignore
   */
  static Integer getDateToInteger(LocalDate date) {
    return Integer.valueOf(format(date, "yyyyMMdd"));
  }

  /**
   * 当前日期.
   *
   * @return ignore
   */
  static Integer nowToInteger() {
    return Integer.valueOf(format(LocalDate.now(), "yyyyMMdd"));
  }

  /**
   * 获取当前time.
   */
  static Timestamp nowTimestamp() {
    return new Timestamp(
        LocalDate.now().atStartOfDay(DateZoneOffset.DEFAULT_ZONE_OFF_SET).toInstant().toEpochMilli()
    );
  }

  /**
   * 转换当前日期格式.
   *
   * @param pattern 格式
   * @return 格式化后的
   */
  static String format(String pattern) {
    return LocalDate.now().format(DateTimeFormatter.ofPattern(pattern));
  }

  /**
   * 转换当前日期格式.
   *
   * @param localDate 日期
   * @param pattern   格式
   * @return 格式化后的
   */
  static String format(LocalDate localDate, String pattern) {
    return localDate.format(DateTimeFormatter.ofPattern(pattern));
  }

  /**
   * 转换当前日期格式.
   */
  static String format(LocalDate localDate, DateFormatEnum pattern) {
    return localDate.format(DateTimeFormatter.ofPattern(pattern.getPattern()));
  }

  /**
   * 转换当前日期格式.
   *
   * @param pattern 格式
   * @return 格式化后的
   */
  static String formatNow(String pattern) {
    return LocalDate.now().format(DateTimeFormatter.ofPattern(pattern));
  }

}
