package com.codvision.commoncore.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author codvision
 */
public class DateUtil extends cn.hutool.core.date.DateUtil {
    public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String STANDARD_DATE_FORMAT = "yyyy-MM-dd";

    public static final String STANDARD_DATE_NO_UNDERLINE_FORMAT = "yyyyMMdd";

    public static final String FULL_DATE = "yyyyMMddHHmmss";


    public static Date getSomeWeekAgoDate(Date date, int weeks) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, -weeks);
        Date someWeeksAgo = calendar.getTime();
        return someWeeksAgo;
    }

    /**
     * 获取N个月前日期
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getSomeMonthAgoDate(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -month);
        Date someMonthAgo = calendar.getTime();
        return someMonthAgo;
    }

    /**
     * 获取N年前日期
     *
     * @param date
     * @return
     */
    public static Date getSomeYearAgoDate(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -year);
        Date someYearAgo = calendar.getTime();
        return someYearAgo;
    }

    public static String strToStr(String strDate) {
        Date date = new Date();
        try {
            //先按照原格式转换为时间
            date = new SimpleDateFormat("yyyyMMddHHmmss").parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //再将时间转换为对应格式字符串
        String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        return str;
    }

    /**
     * 根据系统时间返回一串无符号字符串
     */
    public static String toString(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return simpleDateFormat.format(date);
    }

    /**
     * 根据系统时间返回一串无符号字符串
     */
    public static String monthToString(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
        return simpleDateFormat.format(date);
    }

    /**
     * 根据系统时间返回一串无符号字符串
     */
    public static String dayToString(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        return simpleDateFormat.format(date);
    }

    /**
     * 根据系统时间返回一串无符号字符串
     */
    public static String toStringFor16(Date date, String value) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String data = simpleDateFormat.format(date);
        Random rome = new Random();
        int last = rome.nextInt(90000000) + 10000000;
        return value + data + last;
    }

    public static Date toDate(String date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return simpleDateFormat.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将一个字符串转换成日期格式
     *
     * @param date    字符串日期
     * @param pattern 日期格式
     * @return date
     */
    public static Date toDate(String date, String pattern) {
        if ("".equals("" + date)) {
            return null;
        }
        if (pattern == null) {
            pattern = STANDARD_DATE_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern, Locale.ENGLISH);
        Date newDate = new Date();
        try {
            newDate = sdf.parse(date);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return newDate;
    }


    public static String sdf(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(date);
    }

    public static String getMonthBeginTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        return sdf.format(c.getTime());
    }


    public static String getMonthEndTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return sdf.format(c.getTime());
    }

    public static String getMonthBeginTimeOfLastYear() {

        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        c.add(Calendar.MONTH, 0);
        c.add(Calendar.YEAR, -1);
        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        return sdf.format(c.getTime());
    }


    public static String getMonthEndTimeOfLastYear() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.add(Calendar.YEAR, -1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return sdf.format(c.getTime());
    }


    public static String getToday() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date());
    }


    /**
     * 获得昨天日期:yyyy-MM-dd  HH:mm:ss
     */
    public static String getYesterdayBeginTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -1);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        return startSdf.format(c.getTime());
    }

    /**
     * 获得昨天日期:yyyy-MM-dd  HH:mm:ss
     */
    public static String getYesterdayEndTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, -1);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return startSdf.format(c.getTime());
    }

    public static String getTodayBeginTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        return sdf.format(new Date());
    }


    public static String getTodayEndTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return sdf.format(new Date());
    }

    public static String getNowDateTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }

    /**
     * 获得明天日期:yyyy-MM-dd  HH:mm:ss
     */
    public static String getTomorrowBeginTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, 1);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        return startSdf.format(c.getTime());
    }

    /**
     * 获得明天日期:yyyy-MM-dd  HH:mm:ss
     */
    public static String getTomorrowEndTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, 1);
        SimpleDateFormat startSdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return startSdf.format(c.getTime());
    }

    /**
     * 获得明天日期:yyyy-MM-dd  time
     */
    public static String getTomorrowTime(String time) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, 1);
        SimpleDateFormat startSdf = new SimpleDateFormat(String.format("yyyy-MM-dd %s", time));
        return startSdf.format(c.getTime());
    }


    public static String getYearBeginTime() {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
        return sdf.format(c.getTime());
    }


    public static String getYearEndTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
        Calendar c = Calendar.getInstance();
        return sdf.format(c.getTime());
    }

    public static String getYearBeginTimeOfLastYear() {

        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-01-01 00:00:00");
        c.add(Calendar.YEAR, -1);
        return sdf.format(c.getTime());
    }


    public static String getYearEndTimeOfLastYear() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-12-31 23:59:59");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.YEAR, -1);
        return sdf.format(c.getTime());
    }


    /**
     * 默认当天
     *
     * @return
     */
    public static Map<String, Integer> getWeekOfMonth() {
        return DateUtil.getWeekOfMonth(DateUtil.getToday());
    }


    /**
     * 当前时间所属周,一周占用两个月的情况下属于上个月
     *
     * @param time
     * @return
     */
    public static Map<String, Integer> getWeekOfMonth(String time) {
        //Calendar周日为一周的第一天
        //1.当月的1号为周日:
        //日期是否为周日 是,周数-1 第一个周日属于上个月最后一周
        //2.当月的1号为周一:
        //日期是否为周日 是,周数-1
        //3.当月的1号为周二--六:
        //日期是否为周日 是,周数-2 否,周数-1 为0属于上个月最后一周
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        int resultYear;
        int resultMonth;
        int resultWeekOfMonth;
        Map<String, Integer> resultMap = new HashMap<>(16);
        try {
            Date parse = sdf.parse(time);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(parse);
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
            int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
            resultYear = year;
            resultMonth = month + 1;

            Calendar monthCalendar = Calendar.getInstance();
            monthCalendar.set(Calendar.YEAR, year);
            monthCalendar.set(Calendar.MONTH, month);
            monthCalendar.set(Calendar.DAY_OF_MONTH, 1);
            int monthDayOfWeek = monthCalendar.get(Calendar.DAY_OF_WEEK);

            if (monthDayOfWeek == Calendar.SUNDAY) {
                if (dayOfWeek == Calendar.SUNDAY) {
                    if (dayOfMonth == 1) {
                        if (month == 0) {
                            resultWeekOfMonth = getLastWeekOfMonth(year - 1, 11);
                            resultYear = year - 1;
                            resultMonth = 12;
                        } else {
                            resultWeekOfMonth = getLastWeekOfMonth(year, month - 1);
                            resultMonth = month;
                        }
                    } else {
                        resultWeekOfMonth = weekOfMonth - 1;
                    }
                } else {
                    resultWeekOfMonth = weekOfMonth;
                }
            } else if (monthDayOfWeek == Calendar.MONDAY) {
                if (dayOfWeek == Calendar.SUNDAY) {
                    resultWeekOfMonth = weekOfMonth - 1;
                } else {
                    resultWeekOfMonth = weekOfMonth;
                }
            } else {
                if (dayOfWeek == Calendar.SUNDAY) {
                    resultWeekOfMonth = weekOfMonth - 2;
                } else {
                    resultWeekOfMonth = weekOfMonth - 1;
                }
                if (resultWeekOfMonth == 0) {
                    if (month == 0) {
                        resultWeekOfMonth = getLastWeekOfMonth(year - 1, 11);
                        resultYear = year - 1;
                        resultMonth = 12;
                    } else {
                        resultWeekOfMonth = getLastWeekOfMonth(year, month - 1);
                        resultMonth = month;
                    }
                }
            }
            resultMap.put("year", resultYear);
            resultMap.put("month", resultMonth);
            resultMap.put("weekOfMonth", resultWeekOfMonth);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return resultMap;
    }


    /**
     * 按月度获取当月最后一周是第几周
     *
     * @param year
     * @param month
     * @return
     */
    private static int getLastWeekOfMonth(int year, int month) {
        int result;
        //当月1号
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 1);

        //当月最后一天
        Calendar lastDayOfMonth = Calendar.getInstance();
        lastDayOfMonth.set(Calendar.YEAR, year);
        lastDayOfMonth.set(Calendar.MONTH, month);
        lastDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
        lastDayOfMonth.roll(Calendar.DAY_OF_MONTH, -1);

        //
        int lastWeekOfMonth = lastDayOfMonth.get(Calendar.WEEK_OF_MONTH);
        //
        int lastDayOfWeek = lastDayOfMonth.get(Calendar.DAY_OF_WEEK);
        //当月1号是周几
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        //如果1号是周日或周一,那么这个月的所有除了周日的日期用Calendar获取的周数与需要的周数是一致的;
        if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.MONDAY) {
            //如果最后一天是周日需要的周数要-1
            if (lastDayOfWeek == Calendar.SUNDAY) {
                result = lastWeekOfMonth - 1;
            } else {
                result = lastWeekOfMonth;
            }
        } else {//1号是周二,三,四,五,六的情况下,这个月的所有除了周日的日期用Calendar获取的周数-1后与需要的周数是一致的;
            //是周日的日期需要-2
            if (lastDayOfWeek == Calendar.SUNDAY) {
                result = lastWeekOfMonth - 2;
            } else {
                result = lastWeekOfMonth - 1;
            }
        }
        return result;
    }

    public static String getWeekBeginTime() {
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        return sdf.format(cal.getTime());
    }


    /**
     * 获取本周的结束时间
     *
     * @return
     */
    public static String getWeekEndTime() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);

        cal.setTime(cal.getTime());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return sdf.format(cal.getTime());
    }

    public static String getSomeHoursAgo(int hours) {
        Date date = new Date(System.currentTimeMillis() - hours * 3600 * 1000L);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static String getSomeHoursLater(int hours) {
        Date date = new Date(System.currentTimeMillis() + hours * 3600 * 1000L);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }


    public static String getSomeDaysAgo(int days) {
        Date date = new Date(System.currentTimeMillis() - days * 86400 * 1000L);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static String getSomeDaysLater(int days) {
        Date date = new Date(System.currentTimeMillis() + days * 86400 * 1000L);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static long getHourLeftMilliseconds() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:59:59");
        try {
            Date end = sdf.parse(sdf2.format(now));

            return end.getTime() - now.getTime();
        } catch (Exception ex) {

        }

        return 0;
    }

    public static long getDayLeftMilliseconds() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime = getTodayEndTime();
        try {
            Date end = sdf.parse(endTime);
            return end.getTime() - now.getTime();
        } catch (Exception ex) {

        }

        return 0;
    }

    public static long getWeekLeftMilliseconds() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime = getWeekEndTime();
        try {
            Date end = sdf.parse(endTime);
            return end.getTime() - now.getTime();
        } catch (Exception ex) {

        }

        return 0;
    }

    public static long getMonthLeftMilliseconds() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime = getMonthEndTime();
        try {
            Date end = sdf.parse(endTime);
            return end.getTime() - now.getTime();
        } catch (Exception ex) {

        }

        return 0;
    }


    public static long getYearLeftMilliseconds() {
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String endTime = getYearEndTime();
        try {
            Date end = sdf.parse(endTime);
            return end.getTime() - now.getTime();
        } catch (Exception ex) {

        }

        return 0;
    }
}
