package com.sonic.frog.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.base.Strings;
import org.apache.commons.lang3.time.FastDateFormat;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;


/**
 * 日期工具类.
 * 
 * @author xi.he
 */
public class DateUtils {

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

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

    public static final String YMDHMS = "yyyyMMddHHmmss";

    public static final String YMD = "yyyyMMdd";

    public static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

    public static final long ONE_DAY_MillIS = 24 * 60 * 60 * 1000;

    public static final ZoneId ZONE_ID = ZoneId.systemDefault();

    public static Date convert(Long timestamp) {
        return new Date(timestamp);
    }

    /**
     * 方法描述：获取当前时间的
     */
    public static Date now() {
        return new Date();
    }


    public static String getNow(String pattern) {
        return FastDateFormat.getInstance(pattern).format(new Date());
    }


    public static Long currentTimeMillis() {
        return System.currentTimeMillis();
    }

    /**
     * 方法描述：格式化日期
     */
    public static String formatDate(Date d, String fmt) {
        return FastDateFormat.getInstance(fmt).format(d);
    }

    public static String formatY_M_D(Date d) {
        return FastDateFormat.getInstance(Y_M_D).format(d);
    }

    public static String formatY_M_D_H_M_S(Date d) {
        return FastDateFormat.getInstance(Y_M_D_H_M_S).format(d);
    }

    public static String formatYMD(Date d) {
        return FastDateFormat.getInstance(YMD).format(d);
    }

    public static String formatYMDHMS(Date d) {
        return FastDateFormat.getInstance(YMDHMS).format(d);
    }


    public static String formatDate(Long date, String fmt) {
        return FastDateFormat.getInstance(fmt).format(date);
    }

    public static String format(Date date, String fmt) {
        return FastDateFormat.getInstance(fmt).format(date);
    }

    public static Date parse(String date, String fmt) {
        try {
            return FastDateFormat.getInstance(fmt).parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseY_M_D(String date) {
        if (Strings.isNullOrEmpty(date)) {
            return null;
        }
        try {
            return FastDateFormat.getInstance(Y_M_D).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseY_M_D_H_M_S(String date) {
        try {
            return FastDateFormat.getInstance(Y_M_D_H_M_S).parse(date);
        } catch (ParseException e) {
            throw new IllegalArgumentException("the date pattern is error!");
        }
    }

    public static Date parseISO8601(String dateText) {
        DateTimeFormatter parser = ISODateTimeFormat.dateTimeNoMillis();
        DateTime dt = parser.parseDateTime(dateText);
        return dt.toDate();
    }

    public static Date parseISO8601Mill(String dateText) {
        DateTimeFormatter parser = ISODateTimeFormat.dateTime();
        DateTime dt = parser.parseDateTime(dateText);
        return dt.toDate();
    }


    public static Date parseYMD(String date) {
        try {
            return FastDateFormat.getInstance(YMD).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseYMDHMS(String date) {
        try {
            return FastDateFormat.getInstance(YMDHMS).parse(date);
        } catch (ParseException e) {
            throw new IllegalArgumentException("the date pattern is error!");
        }
    }

    /**
     * 是否是同一天
     */
    public static boolean isSameDay(Date date, Date date2) {
        if (date == null || date2 == null) {
            return false;
        }
        FastDateFormat df = FastDateFormat.getInstance(Y_M_D);
        return df.format(date).equals(df.format(date2));
    }

    public static Date addMonth(Date date, int interval) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, interval);
        return calendar.getTime();
    }

    public static Date addDay(Date date, int interval) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, interval);
        return calendar.getTime();
    }

    public static Date addHour(Date date, int interval) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, interval);
        return calendar.getTime();
    }

    public static Date addMinute(Date date, int interval) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, interval);
        return calendar.getTime();
    }

    public static Date addSecond(Date date, int interval) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, interval);
        return calendar.getTime();
    }

    /**
     * 获取某一个日期的最小时间
     * @param date
     * @return
     */
    public static Date getDateMinTime(Date date){
        LocalDateTime endDateTime = LocalDateTime.ofInstant(date.toInstant(),ZONE_ID)
                .with(LocalTime.MIN);
        return Date.from(endDateTime.atZone(ZONE_ID).toInstant());
    }
    /**
     * 获取某一个日期的最大时间
     * @param date
     * @return
     */
	public static Date getDateMaxTime(Date date){
        LocalDateTime endDateTime = LocalDateTime.ofInstant(date.toInstant(),ZONE_ID)
                .with(LocalTime.MAX);
        return Date.from(endDateTime.atZone(ZONE_ID).toInstant());
    }

    /**
     * 获取endDate与startDate日期相隔天数
     *
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return
     */
    public static Long differentDays(Date startDate,Date endDate) {
        if (startDate == null || endDate == null) {
            return 0L;
        }
        return (endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取endDate与startDate日期之间的日期列表，按pattern格式化
     *
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param pattern 格式化规则
     * @return
     */
    public static List<String> differentDaysStr(Date startDate, Date endDate,String pattern) {
        List<String> daysList = new ArrayList<>(Arrays.asList(DateUtils.format(startDate,pattern)));
        long days = differentDays(startDate,endDate);
        for (int i = 1; i < days+1; i++) {
            daysList.add(format(addDay(startDate,i),pattern));
        }
        return daysList;
    }

    public static List<String> getDays(String startTime, String endTime) {
        List<String> result = new ArrayList<String>();
        try {
            if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
                return null;
            }
            //1、定义转换格式
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

            Date start = df.parse(startTime);
            Date end = df.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);
            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);

            result.add(startTime);
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
            while (tempStart.before(tempEnd)) {
                result.add(df.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }
            if (!startTime.equals(endTime)) {
                result.add(endTime);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }



    public static Long getIntervalSeconds(Date start, Integer intervalMin) {
        if (start == null) {
            return 0L;
        }
        long intervalSeconds = start.getTime() + intervalMin * 60 * 1000 - System.currentTimeMillis();
        return intervalSeconds > 0L ? intervalSeconds : 0L;
    }

    public static void main(String[] args){
        String text = "2020-02-08T15:20:19Z";
        DateTimeFormatter parser = ISODateTimeFormat.dateTimeNoMillis();
        DateTime dt = parser.parseDateTime(text);
        DateTimeFormatter formatter = DateTimeFormat.mediumDateTime();
        System.out.println(formatter.print(dt));
    }

    public static String toFormatDate(String strDate) {
        try {
            Date date = new SimpleDateFormat("yyyyMMdd").parse(strDate);
            return new SimpleDateFormat("yyyy-MM-dd").format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}
