package com.wuban.tron.explore.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;

/**
 * @author sky
 *
 **/
public class DateUtil {
    private final static int WEEK_DAY_NUM = 7;
    private final static int HOUR_16_PM = 16;
    private final static int MINTUES_10 = 10;

    public static final String PATTERN_YMD = "yyyy-MM-dd";
    public static final String PATTERN_YMD_HMS = "yyyy-MM-dd HH:mm:ss";

    /***
     * 毫秒数据格式化时间
     * @param date 时间毫秒
     * @return 格式为(HH mm ss)的时间字符串
     */
    public static String getFormatTime(final long date) {
        return getFormatTime(new Date(date));
    }

    /**
     * 格式化为时间(HH:mm:ss)
     *
     * @param date 日期类型
     * @return 格式为(HH mm ss)的时间字符串
     */
    public static String getFormatTime(final Date date) {
        return getFormatDate(date, "HH:mm:ss");
    }

    /**
     * 格式化为时间(yyyy-MM-dd HH:mm)
     *
     * @param date
     * @return
     */
    public static String getFormatDateTimeMinute(final Date date) {
        return getFormatDate(date, "yyyy-MM-dd HH:mm");
    }

    /**
     * 格式化为时间(yyyy-MM-dd HH:mm) 获取分钟数
     *
     * @param date
     * @return
     */
    public static Date getDateTimeMinute(final Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 就获取今天今天0点时间
     *
     * @return
     */
    public static Date getToday() {
        final Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取时间A与B之间的分钟差
     *
     * @param dateA
     * @param dateB
     * @return
     */
    public static long betweenMinute(final Date dateA, final Date dateB) {
        final long between = dateB.getTime() - dateA.getTime();
        return between / (60 * 1000);
    }

    /**
     * 获取当前格式化时间（HH:mm:ss）
     *
     * @return HH:mm:ss格式的时间字符串
     */
    public static String getCurrentFormatTime() {
        return getFormatDate(new Date());
    }

    /**
     * 格式化日期为(yyyyMMdd)
     *
     * @param date 日期类型
     * @return 格式为(yyyyMMdd)的日期字符串
     */
    public static String getFormatDate(final Date date) {
        return getFormatDate(date, "yyyyMMdd");
    }

    /**
     * 格式化日期为(yyyyMMdd)
     *
     * @param date 整型日期
     * @return 格式为(yyyy - MM - dd HH : mm : ss)的日期字符串
     */
    public static String getFormatDate(final long date) {
        final Date d = new Date(date);
        return getFormatDate(d, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 格式化为日期(pattern)
     *
     * @param date    日期类型
     * @param pattern 日期时间模式
     * @return 格式为(pattern)的日期字符串
     */
    public static String getFormatDate(final Date date, final String pattern) {
        final SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * @param date
     * @return
     */
    public static int getWeekOfDate(final Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w <= 0) {
            w = WEEK_DAY_NUM;
        }
        return w;
    }

    /**
     * @param hour
     * @return
     */
    public static long getTodayForHour(final int hour) {
        final Calendar beginningOfDayCalendar = Calendar.getInstance();
        beginningOfDayCalendar.set(Calendar.HOUR_OF_DAY, hour);
        beginningOfDayCalendar.set(Calendar.MINUTE, 0);
        beginningOfDayCalendar.set(Calendar.SECOND, 0);
        final long beginningOfDayInMillis = beginningOfDayCalendar.getTimeInMillis();
        final Date beginningOfDayDate = new Date(beginningOfDayInMillis);
        return beginningOfDayDate.getTime();
    }

    /**
     * date 日期加上或减去几天
     *
     * @param date
     * @param days
     * @return
     */
    public static Date addDays(final Date date, final int days) {
        final Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    /**
     * date 日期加上或减去几天
     *
     * @param dateStr
     * @param days
     * @return
     */
    public static Date addDays(final String dateStr, final int days) {
        Date date;

        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            date = format.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }

        final Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    /***
     * 获取季度月最后一个周5
     * @return
     */
    public static String getSeasonFriday() {
        final Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, getSeason(calendar.getTime()) + 1);
        //获取前一个月4月1日
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        //3月31日
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.add(Calendar.DAY_OF_MONTH, Calendar.FRIDAY - calendar.get(Calendar.DAY_OF_WEEK));
        return getFormatDate(calendar.getTime());
    }

    /**
     * 获取当前月所属的季度
     * <p>
     * 1 第一季度
     * 2 第二季度
     * 3 第三季度
     * 4 第四季度
     *
     * @param date
     * @return 1|2|3|4
     */
    public static int getSeason(final Date date) {
        final Calendar c = Calendar.getInstance();
        c.setTime(date);
        final int month = c.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                return Calendar.MARCH;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                return Calendar.JUNE;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                return Calendar.SEPTEMBER;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                return Calendar.DECEMBER;
            default:
                return Calendar.MARCH;
        }
    }

    /**
     * 格式化时间
     *
     * @param date
     * @return
     */
    public static Long getDateFromDateStr(String date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            Date dateTime = format.parse(date);
            return dateTime.getTime();
        } catch (ParseException e) {
            return null;
        }
    }

    public static String regularDateTimeFromDate(final Date date) {
        final DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_INSTANT;
        return isoLocalDateTime.format(date.toInstant());
    }

    public static String regularDateTimeFromLong(final Long date) {
        return regularDateTimeFromDate(new Date(date));
    }

    public static Long getTimestampFromISODateStr(final String isoDate) {
        return getDateFromISODateStr(isoDate).getTime();
    }

    public static Date getDateFromISODateStr(final String isoDate) {
        final DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_INSTANT;
        final TemporalAccessor accessor = timeFormatter.parse(isoDate);

        return Date.from(Instant.from(accessor));
    }
}
