package cn.com.ty.lift.batch.applet.util;

import cn.com.ty.lift.batch.applet.constants.DataStatisticsConstants;
import cn.com.ty.lift.batch.applet.dao.model.BaseDataModel;
import cn.com.ty.lift.batch.applet.dao.model.request.CommonRequest;
import cn.hutool.core.date.DatePattern;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author huangyuan
 * @date 2020/2/4
 * @description
 */
public class DataStatisticsUtil {

    /**
     * @param
     * @return
     * @description 获取从1月到当前月份的 月数值->条数
     * @date 2020/2/4 3:09 下午
     */
    public static Map<String, Long> initDateMap() {
        Map<String, Long> monthToCount = new HashMap<>();
        int month = LocalDateTime.now().getMonthValue();
        for (int i = 1; i <= month; i++) {
            //小于10的月份前面加0
            if (i < 10) {
                monthToCount.put("0" + i, 0L);
            } else {
                monthToCount.put(i + "", 0L);
            }
        }
        return monthToCount;
    }

    /**
     * @param
     * @return
     * @description 获取当前年份的最开始的时间
     * @date 2020/2/4 3:37 下午
     */
    public static LocalDateTime getYearFirstTime() {
        return LocalDateTime.of(LocalDateTime.now().getYear(), 1, 1, 0, 0, 0);
    }

    /**
     * @param
     * @return
     * @description 获取当年最后的时间
     * @date 2020/6/2 2:37 下午
     */
    public static LocalDateTime getYearLastTime() {
        return LocalDateTime.of(LocalDateTime.now().getYear(), 12, 31, 0, 0, 0);
    }

    /**
     * @param
     * @return
     * @description 获取当前年份的最开始的时间
     * @date 2020/2/4 3:37 下午
     */
    public static LocalDateTime getYearFirstTime(int year) {
        return LocalDateTime.of(year, 1, 1, 0, 0, 0);
    }

    /**
     * @param
     * @return
     * @description 获取指定年的最后一天
     * @date 2020/5/25 11:13 上午
     */
    public static LocalDateTime getYearLastTime(int year) {
        return LocalDateTime.of(year, 12, 31, 0, 0, 0);
    }

    /**
     * @param localDateTime 时间数据
     * @return
     * @description 获取时间的月份值(字符串)
     * @date 2020/2/4 4:31 下午
     */
    public static String getMonthStr(LocalDateTime localDateTime) {
        //为空返回0
        if (localDateTime == null) {
            return "0";
        }
        int month = localDateTime.getMonthValue();
        if (month < 10) {
            return "0" + month;
        }
        return month + "";
    }

    /**
     * @param localDateTime 时间数据
     * @description 获取时间的月份值(数字)
     * @date 2020/2/7 3:06 下午
     */
    public static int getMonth(LocalDateTime localDateTime) {
        //为空返回0
        if (localDateTime == null) {
            return 0;
        }
        return localDateTime.getMonthValue();
    }

    /**
     * @param localDate 时间数据
     * @description 获取时间的月份值(数字)
     * @date 2020/2/7 3:06 下午
     */
    public static int getMonth(LocalDate localDate) {
        //为空返回0
        if (localDate == null) {
            return 0;
        }
        return localDate.getMonthValue();
    }

    /**
     * @param afterTime  较大时间
     * @param beforeTime 较小时间
     * @return Long 差值
     * @description 请两个时间的分钟差值
     * @date 2020/2/5 10:02 上午
     */
    public static Long getDiffMinute(LocalDateTime beforeTime, LocalDateTime afterTime) {
        if (beforeTime != null && afterTime != null) {
            Duration duration = Duration.between(beforeTime, afterTime);
            return duration.toMinutes();
        }
        return 0L;
    }

    /**
     * @param
     * @return
     * @description 给请求类设置年初到现在的时间
     * @date 2020/2/7 3:51 下午
     */
    public static void setBeginYearToNow(CommonRequest commonRequest) {
        //年初时间
        commonRequest.setStartTimeDate(getYearFirstTime());
        //当前时间
        commonRequest.setEndTimeDate(LocalDateTime.now());
    }

    /**
     * @param
     * @return
     * @description 给请求类设置年初到现在的时间
     * @date 2020/2/7 3:51 下午
     */
    public static void setBeginYearToNow(int year, CommonRequest commonRequest) {
        //年初时间
        commonRequest.setStartTimeDate(getYearFirstTime(year));
        //当前时间
        commonRequest.setEndTimeDate(LocalDateTime.now());
    }

    /**
     * @param bigDecimalValue
     * @return
     * @description 获取 BigDecimal的值
     * @date 2020/2/7 8:11 下午
     */
    public static double getDoubleValue(BigDecimal bigDecimalValue) {
        return bigDecimalValue != null ? bigDecimalValue.doubleValue() : 0d;
    }

    /**
     * 根据map的key排序
     *
     * @param map    待排序的map
     * @param isDesc 是否降序，true：降序，false：升序
     * @return 排序好的map
     */
    public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map, boolean isDesc) {
        Map<K, V> result = Maps.newLinkedHashMap();
        if (isDesc) {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByKey().reversed())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        } else {
            map.entrySet().stream().sorted(Map.Entry.comparingByKey())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        }
        return result;
    }

    /**
     * 根据map的value排序
     *
     * @param map    待排序的map
     * @param isDesc 是否降序，true：降序，false：升序
     * @return 排序好的map
     */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, boolean isDesc) {
        Map<K, V> result = Maps.newLinkedHashMap();
        if (isDesc) {
            map.entrySet().stream().sorted(Map.Entry.<K, V>comparingByValue().reversed())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        } else {
            map.entrySet().stream().sorted(Map.Entry.comparingByValue())
                    .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        }
        return result;
    }

    /**
     * @param subField 模糊查询字段
     * @param field    字段
     * @return
     * @description 查看字符串是否包含子字符串
     * @date 2020/2/10 6:43 下午
     */
    public static boolean strMatch(String subField, String field) {
        if (StringUtils.isNotBlank(subField) && StringUtils.isNotBlank(field)) {
            Pattern pattern = Pattern.compile(".*" + subField + ".*");
            return pattern.matcher(field).find();
        }
        return false;
    }

    /**
     * @param timeInterval 时间间隔 正值:之后的时间 负值:之前的时间
     * @param intervalType 间隔类型 : intervalYear 年
     *                     intervalMonth 月
     *                     intervalDay 天
     *                     intervalMinute 分
     * @return
     * @description 初始化commonRequest请求对象
     * @date 2020/2/10 12:07 下午
     */
    public static CommonRequest initCommonRequest(Long timeInterval, String intervalType) {
        CommonRequest commonRequest = new CommonRequest();
        LocalDateTime now = LocalDateTime.now();
        //获取时间间隔前的时间, 默认为年份间隔
        LocalDateTime beforeTime = now.plusYears(timeInterval);
        //通过时间间隔类型来计算时间
        switch (intervalType) {
            //月份间隔
            case DataStatisticsConstants.INTERVAL_TYPE_MONTH:
                beforeTime = now.plusMonths(timeInterval);
                break;
            //天间隔
            case DataStatisticsConstants.INTERVAL_TYPE_DAY:
                beforeTime = now.plusDays(timeInterval);
                break;
            //小时间隔
            case DataStatisticsConstants.INTERVAL_TYPE_HOUR:
                beforeTime = now.plusHours(timeInterval);
                break;
            //分钟间隔
            case DataStatisticsConstants.INTERVAL_TYPE_MINUTE:
                beforeTime = now.plusMinutes(timeInterval);
                break;
        }
        //获取格式化后的时间字符串
        //起始时间
        commonRequest.setStartTimeDate(beforeTime);
        commonRequest.setStartTimeDateStr(beforeTime.format(
                DateTimeFormatter.ofPattern(DataStatisticsConstants.DATA_STATISTICS_TIME_FORMAT)
        ));
        //终止时间
        commonRequest.setEndTimeDate(now);
        commonRequest.setEndTimeDateStr(now.format(
                DateTimeFormatter.ofPattern(DataStatisticsConstants.DATA_STATISTICS_TIME_FORMAT)
        ));
        return commonRequest;
    }

    /**
     * @param timeStr       时间字符串
     * @param formatPattern 格式
     * @return
     * @description 将指定格式的时间字符串转化为 LocalDateTime对象
     * @date 2020/2/11 11:14 上午
     */
    public static LocalDateTime getLocalDateTimeFromStr(String timeStr, String formatPattern) {
        if (StringUtils.isNotBlank(timeStr)) {
            return LocalDateTime.parse(timeStr,
                    DateTimeFormatter.ofPattern(formatPattern));
        }
        return null;
    }

    /**
     * @param timeStr       时间字符串
     * @param formatPattern 格式
     * @return
     * @description 将指定格式的时间字符串转化为 LocalDate对象
     * @date 2020/2/11 11:14 上午
     */
    public static LocalDate getLocalDateFromStr(String timeStr, String formatPattern) {
        if (StringUtils.isNotBlank(timeStr)) {
            return LocalDate.parse(timeStr,
                    DateTimeFormatter.ofPattern(formatPattern));
        }
        return null;
    }

    /**
     * @return 初始化 map
     * @description 初始化map数据
     * @date 2020/5/22 10:38 上午
     */
    public static Map<Integer, Map<Integer, Long>> initNum() {
        Map<Integer, Map<Integer, Long>> monthToBusiness = new HashMap<>();
        int nowMonth = LocalDate.now().getMonthValue();
        for (int month = 1; month <= nowMonth; month++) {
            Map<Integer, Long> businessStatusToNum = new HashMap<>();
            //计划维保/年检总数量
            businessStatusToNum.put(0, 0L);
            //维保/年检完成数量
            businessStatusToNum.put(1, 0L);
            monthToBusiness.put(month, businessStatusToNum);
        }
        return monthToBusiness;
    }

    /**
     * @return
     * @description
     * @date 2020/6/2 2:56 下午
     */
    public static Map<Integer, Map<Integer, Long>> initAnnualNum() {
        Map<Integer, Map<Integer, Long>> monthToBusiness = new HashMap<>();
        int nowMonth = LocalDate.now().getMonthValue();
        for (int month = 1; month <= nowMonth; month++) {
            Map<Integer, Long> businessStatusToNum = new HashMap<>();
            //年检总数量
            businessStatusToNum.put(0, 0L);
            //年检完成数量
            businessStatusToNum.put(1, 0L);
            //完成总和
            businessStatusToNum.put(2, 0L);
            monthToBusiness.put(month, businessStatusToNum);
        }
        return monthToBusiness;
    }

    /**
     * @param commonRequest commonRequest
     * @description 初始化时间 年初 - 当前时间
     * @date 2020/5/22 11:24 上午
     */
    public static void initCommonRequest(CommonRequest commonRequest) {
        //设置年初时间
        String yearStartTime = getYearFirstTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
        //设置当前时间
        String nowEndTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
        commonRequest.setStartTimeDateStr(yearStartTime);
        commonRequest.setEndTimeDateStr(nowEndTime);
    }

    /**
     * @param value 值
     * @return long 值
     * @description 去除空值的情况
     * @date 2020/4/24 5:18 下午
     */
    public static long getLongValue(Long value) {
        if (value != null) {
            return value;
        }
        return 0L;
    }
}
