package com.base.orbit.lucene.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

public class TimeUtil {
    /**
     * 默认⽇期格式
     */
    private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
    private static final String PLAIN_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /**
     * 默认⽇期格式
     */
    private static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);
    private static final DateTimeFormatter PLAIN_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(PLAIN_PATTERN);
    private static final ZoneId DEFAULT_ZONE_ID = ZoneId.systemDefault();

    /**
     * LocalDateTime 转 字符串，指定⽇期格式
     *
     * @param localDateTime
     * @param pattern
     * @return
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        String timeStr = formatter.format(localDateTime.atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }

    public static String format(LocalDateTime localDateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);
        String timeStr = formatter.format(localDateTime.atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }


    /**
     * Date 转 字符串, 指定⽇期格式
     *
     * @param time
     * @param pattern
     * @return
     */
    public static String format(Date time, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        String timeStr =
                formatter.format(time.toInstant().atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }

    /**
     * Date 转 字符串，默认⽇期格式
     *
     * @param time
     * @return
     */
    public static String format(Date time) {
        String timeStr = DEFAULT_DATE_TIME_FORMATTER.format(time.toInstant().atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }

    /**
     * timestamp 转 字符串，默认⽇期格式
     *
     * @param timestamp
     * @return
     */
    public static String format(long timestamp) {
        String timeStr = DEFAULT_DATE_TIME_FORMATTER.format(new Date(timestamp).toInstant().atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }

    /**
     * timestamp 转 字符串，默认⽇期格式
     *
     * @param timestamp
     * @return
     */
    public static String plainFormat(long timestamp) {
        String timeStr = PLAIN_DATE_TIME_FORMATTER.format(new Date(timestamp).toInstant().atZone(DEFAULT_ZONE_ID));
        return timeStr;
    }

    /**
     * 字符串 转 Date
     *
     * @param time
     * @return
     */
    public static Date strToDate(String time) {
        LocalDateTime localDateTime = LocalDateTime.parse(time, PLAIN_DATE_TIME_FORMATTER);
        return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());
    }

    /**
     * 字符串转LocalDateTime
     *
     * @param time
     * @return
     */
    public static LocalDateTime strToLocalDatetime(String time) {
        LocalDateTime localDateTime = LocalDateTime.parse(time, DEFAULT_DATE_TIME_FORMATTER);
        return localDateTime;
    }

    /**
     * 获取当天剩余的秒数,⽤于流量包过期配置
     *
     * @param currentDate
     * @return
     */
    public static Integer getRemainSecondsOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault()).plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(), ZoneId.systemDefault());
        long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);
        return (int) seconds;
    }

    /**
     * 将时间戳转为Date日期
     *
     * @param mill 时间戳
     * @return
     */
    public static String millsCastTime(Integer mill) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PLAIN_PATTERN);
        return simpleDateFormat.format(new Date(Long.valueOf(mill.toString() + "000")));
    }

    /**
     * 访问时间-3分钟=测控时间
     *
     * @param earlyTime 访问时间
     * @return
     */
    public static String cxTime(String earlyTime) {
        long min = 3 * 60 * 1000; // 3分钟
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PLAIN_PATTERN);
        try {
            Date date = simpleDateFormat.parse(earlyTime);
            Date cxDate = new Date(date.getTime() - min);
            String cxTime = simpleDateFormat.format(cxDate);
            return cxTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 访问时间+3分钟=数传时间
     *
     * @param lateTime 访问时间
     * @return
     */
    public static String scTime(String lateTime) {
        long min = 3 * 60 * 1000; // 3分钟
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PLAIN_PATTERN);
        try {
            Date date = simpleDateFormat.parse(lateTime);
            Date cxDate = new Date(date.getTime() + min);
            String scTime = simpleDateFormat.format(cxDate);
            return scTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 取出最早的时间
     *
     * @param accessTimes 时间集合
     * @return
     */
    public static String getEarlyTime(List<String> accessTimes) {
        String accessTime;
        if (accessTimes.size() == 1) {
            accessTime = accessTimes.get(0);
        } else {
            List<Long> longs = timeCastLong(accessTimes);
            Long aLong = longs.stream().min(Comparator.comparing(Long::longValue)).get();
            accessTime = plainFormat(aLong);
        }
        return accessTime;
    }

    /**
     * 取出最晚的时间
     *
     * @param accessTimes 时间集合
     * @return
     */
    public static String getLateTime(List<String> accessTimes) {
        String accessTime;
        if (accessTimes.size() == 1) {
            accessTime = accessTimes.get(0);
        } else {
            List<Long> longs = timeCastLong(accessTimes);
            Long aLong = longs.stream().max(Comparator.comparing(Long::longValue)).get();
            accessTime = plainFormat(aLong);
        }
        return accessTime;
    }

    /**
     * 将日期转为时间戳
     *
     * @param accessTimes
     * @return
     */
    public static List<Long> timeCastLong(List<String> accessTimes) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PLAIN_PATTERN);
        List<Long> longs = new ArrayList<>();
        for (String time : accessTimes) {
            try {
                Date date = simpleDateFormat.parse(time);
                longs.add(date.getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return longs;
    }

    /**
     *  计算两时间差
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static long totalMin(LocalDateTime startTime, LocalDateTime endTime){
        Duration duration = Duration.between(startTime, endTime);
        long millis = duration.toMillis();
        return millis;
    }
}
