package com.zcxk.utils;

import com.zcxk.evaluation.enums.EvaluationCycleEnums;
import com.zcxk.evaluation.enums.EvaluationResultStatus;
import com.zcxk.evaluation.vo.EvaluationItemVo;
import com.zcxk.evaluation.vo.EvaluationResultVo;
import com.zcxk.exception.ServiceException;
import com.zcxk.util.DatesUtil;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName EvaluationJobUtil
 * @Description: TODO
 * @Author lihui
 * @Date 2021/5/10
 * @Version V1.0
 **/
public class EvaluationUtil {

    /**
     * 考评周期格式化
     */
    private static final String DATE_STRING = "%s年%s";

    /**
     * 3月
     */
    private static final int MARCH = 3;

    /**
     * 6月
     */
    private static final int JUNE = 6;

    /**
     * 9月
     */
    private static final int SEPTEMBER = 9;

    /**
     * 12月
     */
    private static final int DECEMBER = 12;

    /**
     * 第一季度
     */
    private static final String Q1 = "1";

    /**
     * 第二度
     */
    private static final String Q2 = "2";

    /**
     * 第三季度
     */
    private static final String Q3 = "3";

    /**
     * 第四季度
     */
    private static final String Q4 = "4";

    /**
     * 工单类型
     */
    static List<Integer> workList = Arrays.asList(1,2,3,4,5,6,10);

    /**
     * @Author lihui
     * @Description 是否是同月
     * @Date 18:14 2021/5/11
     * @Param [month]
     * @return boolean
     **/
    public static boolean sameMonth(int month){
        return Calendar.getInstance().get(Calendar.MONTH) + 1  == month;
    }

    /***
     * 计算按时完成率=(完成数-延期完成数)/任务总数
     * @author lihui
     * @date 15:35 2021/5/21
     * @param completeCount :
     * @param delayCompleteCount :
     * @param totalCount :
     * @return java.math.BigDecimal
     **/
    public static BigDecimal onTimeCompletionRate(int completeCount, int delayCompleteCount, int totalCount){
        return divide(completeCount - delayCompleteCount,
                totalCount, 4).multiply(new BigDecimal("100"));
    }

    /**
     * 判断是不是工单
     * @param orderTypeId
     * @return
     */
    public static boolean isWork(Integer orderTypeId){
        return workList.contains(orderTypeId);
    }

    /***
     * 格式化考评周期时间
     * @author lihui
     * @date 11:00 2021/5/19
     * @param cycle :
     * @param year :
     * @param month :
     * @return java.lang.String
     **/
    public static String formatCycle(int cycle, String year, String month){
        // 格式化月度
        if (cycle == EvaluationCycleEnums.MONTH.getType()) {
            return String.format(DATE_STRING, year, month + "月");
        }
        // 格式化年度
        if (cycle == EvaluationCycleEnums.YEAR.getType()) {
            return String.format(DATE_STRING, year, "");
        }
        // 格式化季度
        switch (Integer.parseInt(month)) {
            case MARCH :
                month = Q1;
                break;
            case JUNE :
                month = Q2;
                break;
            case SEPTEMBER :
                month = Q3;
                break;
            case DECEMBER :
                month = Q4;
                break;
            default:
                month = "";
        }
        return String.format(DATE_STRING, year, month + "季度");
    }

    public static Integer toInteger(Long lon) {
        return lon == null ? null : lon.intValue();
    }

    public static BigDecimal divide(Integer completeCount, Integer total, int scale){
        String defaultValue = "0";
        BigDecimal bigDecimalComplete =  new BigDecimal(completeCount.toString());
        BigDecimal bigDecimalTotal =  new BigDecimal(total.toString());
        if (bigDecimalTotal.compareTo(new BigDecimal(defaultValue)) == 0){
            return new BigDecimal(defaultValue);
        }
        return bigDecimalComplete.divide(bigDecimalTotal, scale, RoundingMode.HALF_UP);
    }

    /**
    * @Author lihui
    * @Description 转换分钟
    * @Date 17:11 2021/5/11
    * @Param [dataLimit]
    * @return int
    **/
    public static int minute(String dataLimit){
        if (StringUtils.isEmpty(dataLimit)){
            return 0;
        }
        return new BigDecimal(dataLimit).multiply(new BigDecimal("60")).intValue();
    }

    /**
    * @Author lihui
    * @Description 完成状态
    * @Date 17:08 2021/5/11
    * @Param [status]
    * @return boolean
    **/
    public static boolean completed(Integer status){
        return status == 2 || status == 3 ;
    }

    /**
     * @Author lihui
     * @Description 计算是否延期完成
     * @Date 11:06 2021/5/11
     * @Param [finishDate ：最终完成时间, planFinishDate：预计完成时间, addMinute：可延期的时间]
     * @return boolean
     **/
    public static boolean isDelay(Date finishDate, Date planFinishDate, int addMinute){
        if (finishDate == null || planFinishDate == null) {
            return false;
        }
        return finishDate.after(DatesUtil.addMinuteOfDate(planFinishDate,addMinute));
    }

    public static boolean containsType(List<EvaluationItemVo> itemEntityList, Integer type){
        List<String> list = itemEntityList.stream().map(EvaluationItemVo::getCycle).collect(Collectors.toList());
        for (String str: list) {
            if (str.indexOf(type.toString()) != -1) {
                return true;
            }
        }
        return false;
    }



    private static Integer calendarMonth(Integer calendarMonth){
        switch (calendarMonth){
            case 1 :
                return 4;
            case 4 :
                return 1;
            case 7 :
                return 2;
            case 10 :
                return 3;
            default: ;
        }
        return null;
    }

    public static String getStartTime(int cycle, int day) {
        LocalDate localDate = LocalDate.now();
        if (cycle == EvaluationCycleEnums.MONTH.getType()) {
            localDate = localDate.plusMonths(-1);
        }

        if (cycle == EvaluationCycleEnums.QUARTER.getType()){
            Integer type = calendarMonth(localDate.getMonthValue());
            if (type == null) {
                return null;
            }
            int month = type == 1 ? 1 :
                        type == 2 ? 4 :
                        type == 3 ? 7 :
                        type == 4 ? 10 : null;
            localDate = type == 4 ? localDate.plusYears(-1) : localDate;
            localDate = localDate.withMonth(month);
        }

        if (cycle == EvaluationCycleEnums.YEAR.getType()){
            localDate = localDate.plusYears(-1);
            localDate = localDate.withMonth(1);
        }
        localDate = localDate.withDayOfMonth(day);
        return localDate.toString() + " 00:00:00";
    }

    public static String getEndTime(int cycle, int day) {
        LocalDate localDate = LocalDate.now();

        if (cycle == EvaluationCycleEnums.MONTH.getType()) {
            localDate = day == 1 ? localDate.plusMonths(-1) : localDate;
        }

        if (cycle == EvaluationCycleEnums.QUARTER.getType()){
            Integer type = calendarMonth(localDate.getMonthValue());
            if (type == null) {
                return null;
            }
            int month = type == 1 ? 4 :
                        type == 2 ? 7 :
                        type == 3 ? 10 :
                        type == 4 ? 1 : null;
            // 设置月份
            if (type == 4 && day == 1 ){
                localDate = localDate.plusMonths(-1);
            } else {
                localDate = localDate.withMonth(day == 1 ? month -1 : month);
            }
        }

        if (cycle == EvaluationCycleEnums.YEAR.getType()){
            localDate = localDate.withMonth(1);
            localDate = day == 1 ? localDate.plusMonths(-1) : localDate;
        }

        localDate = day != 1 ? localDate.withDayOfMonth(day - 1) : localDate.with(TemporalAdjusters.lastDayOfMonth());
        return localDate.toString() + " 23:59:59";
    }

    public static String getStartTime(int cycle, int year, int newMonth, int day) {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.withYear(year);
        localDate = localDate.withMonth(newMonth);
        if (cycle == EvaluationCycleEnums.MONTH.getType()) {
            localDate = localDate.plusMonths(-1);
        }

        if (cycle == EvaluationCycleEnums.QUARTER.getType()){
            int month = newMonth == 1 ? 1 :
                        newMonth == 2 ? 4 :
                        newMonth == 3 ? 7 :
                        newMonth == 4 ? 10 : null;

            localDate = localDate.withMonth(month);
        }

        if (cycle == EvaluationCycleEnums.YEAR.getType()){
            localDate = localDate.plusYears(-1);
            localDate = localDate.withMonth(1);
        }
        localDate = localDate.withDayOfMonth(day);
        return localDate.toString() + " 00:00:00";
    }

    public static String getEndTime(int cycle, int year, int newMonth, int day) {
        LocalDate localDate = LocalDate.now();
        localDate = localDate.withYear(year);
        localDate = localDate.withMonth(newMonth);
        if (cycle == EvaluationCycleEnums.MONTH.getType()) {
            localDate = day == 1 ? localDate.plusMonths(-1) : localDate;
        }

        if (cycle == EvaluationCycleEnums.QUARTER.getType()){
            int month = newMonth == 1 ? 4 :
                        newMonth == 2 ? 7 :
                        newMonth == 3 ? 10 :
                        newMonth == 4 ? 1 : null;
            localDate = localDate.withMonth(month);
            // 设置月份
            localDate = day == 1 ? localDate.plusMonths(-1) : localDate;
            localDate = newMonth == 4 ? localDate.plusYears(1) : localDate;
        }

        if (cycle == EvaluationCycleEnums.YEAR.getType()){
            localDate = localDate.withMonth(1);
            localDate = day == 1 ? localDate.plusMonths(-1) : localDate;
        }

        localDate = day != 1 ? localDate.withDayOfMonth(day - 1) : localDate.with(TemporalAdjusters.lastDayOfMonth());
        return localDate.toString() + " 23:59:59";
    }

    public static LocalDate getLocalDateByCycle(String startTime, String endTime, int cycle){
        // 季度获取后面的时间
        String quarterString = "4,7,10,1";
        boolean isQuarter = cycle == EvaluationCycleEnums.QUARTER.getType();
        String time = isQuarter ? endTime : startTime;
        LocalDate localDate = DatesUtil.formatLocalDate(time);
        if (isQuarter && quarterString.indexOf(localDate.getMonthValue() + "") != -1) {
            localDate = localDate.plusMonths(-1);
        }
        return localDate;
    }

    public static List<List<String>> getExcelTitle(){
        String[] string = new String[]{"No.","用户名","所属公司","所属部门","绩效等级","绩效得分","考评周期"};
        List<List<String>> list = new ArrayList<>();
        for (String str : string) {
            List<String> title = new ArrayList<>();
            title.add(str);
            list.add(title);
        }
        return list;
    }

    public static List<List<String>> getExcelData(List<EvaluationResultVo> evaluationResultVos) {
        List<List<String>> result = new ArrayList<>();
        int total = 1;
        for (EvaluationResultVo evaluationResultVo : evaluationResultVos){
            List<String> list = new ArrayList<>();
            list.add(total + "");
            list.add(evaluationResultVo.getEvaluationBe());
            list.add(evaluationResultVo.getCompanyOrgName());
            list.add(evaluationResultVo.getDeptOrgName());
            list.add(evaluationResultVo.getEvaluationGrade());
            list.add(evaluationResultVo.getValue()!= null ? evaluationResultVo.getValue().toString() : "");
            list.add(evaluationResultVo.getCycle());
            result.add(list);
            total++;
        }
        return result;
    }


    public static String getOrderStatusName(int status){
        switch (status) {
            case 0 :
                return "待处理";
            case 1 :
                return "处理中";
            case 2 :
                return "完成";
            case 3 :
                return "终止";
        }
        return "";
    }


    /***
     * 根据1-4季度，获取对应末尾的月份
     * @author lihui
     * @date 14:53 2021/5/21
     * @param cycle : 季度
     * @return java.lang.Integer
     **/
    public static Integer format(Integer cycle){
        switch (cycle) {
            case 1 :
                return 3;
            case 2 :
                return 6;
            case 3 :
                return 9;
            case 4:
                return 12;
            default:
                throw new ServiceException(EvaluationResultStatus.PARAM_ERROR.getStatus(), EvaluationResultStatus.PARAM_ERROR.getMessage());
        }
    }

    /**
     * 根据1-4季度末尾月份，获取每个季度对应的月份
     * @author lihui
     * @date 14:54 2021/5/21
     * @param month : 月份
     * @return java.util.List<java.lang.Integer>
     **/
    public static List<Integer> formatList(Integer month){
        switch (month) {
            case 3 :
                return Arrays.asList(1,2,3);
            case 6 :
                return Arrays.asList(4,5,6);
            case 9 :
                return Arrays.asList(7,8,9);
            case 12:
                return Arrays.asList(10,11,12);
            default:
                throw new ServiceException(EvaluationResultStatus.PARAM_ERROR.getStatus(), EvaluationResultStatus.PARAM_ERROR.getMessage());
        }
    }

    public static void main(String[] args) {
        System.out.println(EvaluationUtil.minute("0"));
        System.out.println(EvaluationUtil.isDelay(DatesUtil.parseDate("2021-05-19 00:04:59", "yyyy-MM-dd HH:mm:ss"), DatesUtil.parseDate("2021-05-18 23:59:59", "yyyy-MM-dd HH:mm:ss"), 5));
    }

}
