package com.pqs9900.task;

import cn.hutool.core.collection.CollectionUtil;
import com.njcn.pojo.commons.runmanage.IntergralityTable;
import com.njcn.pojo.data.ComInformation;
import com.njcn.utils.UserUtil;
import com.pqs9900.mapper.DataInfo.AlarmInfoMapper;
import com.pqs9900.mapper.linedata.OnlineRateCldMapper;
import com.pqs9900.mapper.linedata.TopStrategyMapper;
import com.pqs9900.pojo.DataInfo.AlarmInfo;
import com.pqs9900.pojo.linedata.*;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

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

/**
 * 每天10.05执行对前一天的装置运行异常情况进行统计存入表pqs_topmsg中
 *
 * @author cdf
 * @date 2021/11/10
 */
public class TopExceptionTask implements Job {
    private static final Logger logger = LoggerFactory.getLogger(TopExceptionTask.class);

    private static final float dayTime = 24 * 60 * 60;


    @Autowired
    private UserUtil userUtil;

    @Autowired
    private AlarmInfoMapper alarmInfoMapper;
    @Autowired
    private TopStrategyMapper topStrategyMapper;
    @Autowired
    private OnlineRateCldMapper onlineRateCldMapper;


    /**
     * 统计每日终端异常通告
     *
     * @author cdf
     * @date 2021/12/16
     */
    public void runTask() {
        long aa = System.currentTimeMillis();
        System.out.println("开始执行++++++++++++++++++++++++++");

        Date[] dates = getYesterday();
        Date startTime = dates[0];
        Date endTime = dates[1];

        Calendar calendarMax = Calendar.getInstance();
        calendarMax.add(Calendar.DAY_OF_MONTH, -1);
        calendarMax.set(Calendar.HOUR_OF_DAY, 0);
        calendarMax.set(Calendar.MINUTE, 0);
        calendarMax.set(Calendar.SECOND, 0);
        calendarMax.set(Calendar.MILLISECOND, 0);

        int lastDay = calendarMax.getActualMaximum(Calendar.DATE);
        calendarMax.set(Calendar.DAY_OF_MONTH, lastDay);
        Date maxTime = calendarMax.getTime();
        System.out.println("本月最大时间" + maxTime);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

/*
        Date startTime = null;
        Date endTime = null;
        Date maxTime = null;
        int lastDay = 31;
        try {
            startTime = sdf.parse("2021-12-10 00:00:00");
            endTime = sdf.parse("2021-12-10 23:59:59");
            maxTime = sdf.parse("2021-12-31 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }*/


        int days = ((int) ((maxTime.getTime() - startTime.getTime()) / (24 * 3600 * 1000))) + 1;
        System.out.println("开始时间" + startTime);
        System.out.println("结束时间" + endTime);

        //判断表中是否已经存在前一天数据
        Integer countData = topStrategyMapper.getTopCount(startTime);
        if (countData > 0) {
            logger.error(startTime + "数据已经存在,是否存在重复运行环境!");
            return;
        }

        //获取告警策略
        Map<Integer, TerminalRun> hashMap = getTopStrategyList();
        if (Objects.isNull(hashMap)) {
            logger.error(new Date() + "终端运行异常判断策略标准为空,请先配置! 方法名TopExceptionTask");
            return;
        }


        HashMap<Integer, DevMsgInfo> alarmMap = new HashMap<>();

        //告警
        List<AlarmInfo> alarmList = alarmInfoMapper.getAlarmTaskByDev(startTime, endTime);

        if (CollectionUtil.isNotEmpty(alarmList)) {

            for (AlarmInfo alarmInfo : alarmList) {
                Integer devIndex = Integer.valueOf(alarmInfo.getTypeIndex());
                if (alarmInfo.getDicLeave() == null) {
                    alarmInfo.setDicLeave(3);
                }
                if (hashMap.containsKey(alarmInfo.getDicLeave())) {
                    String alarmTime = sdf.format(alarmInfo.getOccurredTime());
                    if (alarmMap.containsKey(devIndex)) {
                        DevMsgInfo devMsgInfo = alarmMap.get(devIndex);
                        devMsgInfo.setAlarmCount(devMsgInfo.getAlarmCount() + 1);
                        devMsgInfo.getAlarmDesc().add(alarmTime + " " + alarmInfo.getDescrpiption());
                    } else {
                        DevMsgInfo devMsgInfo = new DevMsgInfo();
                        devMsgInfo.setDevIndex(devIndex);
                        devMsgInfo.setAlarmCount(1);
                        devMsgInfo.setLineGrade(alarmInfo.getDicLeave());
                        List<String> ala = new ArrayList<>();

                        ala.add(alarmTime + " " + alarmInfo.getDescrpiption());
                        devMsgInfo.setAlarmDesc(ala);
                        alarmMap.put(devIndex, devMsgInfo);
                    }

                } else {
                    logger.error("终端运行异常判断策略标准缺失,请先配置! 方法名TopExceptionTask");
                    return;
                }

            }
            //根据策略删除相应装置
            if (alarmMap.size() > 0) {
                Iterator<Map.Entry<Integer, DevMsgInfo>> iterator = alarmMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<Integer, DevMsgInfo> entry = iterator.next();
                    Integer lineGrade = entry.getValue().getLineGrade();
                    if (hashMap.containsKey(lineGrade)) {
                        Integer alarmCount = hashMap.get(lineGrade).getWarnValue();
                        if (entry.getValue().getAlarmCount() < alarmCount) {
                            iterator.remove();
                        }
                    }
                }
            }


        }

        //数据完整性
        Map<Integer, Float> inteList = new HashMap();
        List<IntergralityTable> intergralList = topStrategyMapper.getIntegrityTask(startTime);
        if (CollectionUtil.isNotEmpty(intergralList)) {
            for (IntergralityTable intergralityTable : intergralList) {
                if (intergralityTable.getLineGrade() == null) {
                    intergralityTable.setLineGrade(3);
                }
                if (hashMap.containsKey(intergralityTable.getLineGrade())) {
                    Integer count = hashMap.get(intergralityTable.getLineGrade()).getIntegrityValue();
                    float integrate = Float.parseFloat(intergralityTable.getIntegrity());
                    if (integrate < count) {
                        inteList.put(Integer.parseInt(intergralityTable.getDevice()), integrate);
                    }
                } else {
                    logger.error("终端运行异常判断策略标准缺失,请先配置! 方法名TopExceptionTask");
                    return;
                }
            }
        }

        //中断持续时长
        HashMap<Integer, DevMsgInfo> offMap = new HashMap<>();
        List<TopExceptionParam> devOffList = topStrategyMapper.getOffLineTask(startTime, endTime);
        if (CollectionUtil.isNotEmpty(devOffList)) {
            for (TopExceptionParam map : devOffList) {
                Integer devIndex = map.getDevIndex();

                int time = 3600000;
                if (Objects.isNull(map.getParamIndex())) {
                    map.setParamIndex(3);
                }
                Integer lineGrade = map.getParamIndex();

                if (hashMap.containsKey(lineGrade)) {
                    time = hashMap.get(lineGrade).getOfftimeValue() * 60 * 1000;
                } else {
                    logger.error("终端运行异常判断策略标准缺失,请先配置! 方法名TopExceptionTask");
                    return;
                }

                SimpleDateFormat sDateFormatY = new SimpleDateFormat("yyyy-MM-dd");
                SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                List<ComInformation> comInformations = topStrategyMapper.devMsgInfo(devIndex, startTime, endTime);
                if (CollectionUtil.isNotEmpty(comInformations)) {
                    List<String> dt = new ArrayList<>();
                    for (int i = 0; i < comInformations.size(); i++) {
                        String start = "";
                        String end = "";
                        Date startTmp = null;

                        //第一个记录时间为正常
                        if (i == 0 && (comInformations.get(i).getType() == 1)) {
                            Date endT = comInformations.get(i).getUpdateTime();
                            if (endT.getTime() - startTime.getTime() >= time) {
                                String EndStr = sDateFormat.format(endT);
                                dt.add(sDateFormat.format(startTime) + "至" + EndStr);
                            }
                        }

                        //记录中断时间
                        if (comInformations.get(i).getType() == 0) {
                            startTmp = comInformations.get(i).getUpdateTime();
                            start = sDateFormat.format(startTmp);
                            if (comInformations.size() > 1) {
                                if (i < (comInformations.size() - 1)) {
                                    if (comInformations.get(i + 1).getType() == 1) {
                                        Date endDate = comInformations.get(i + 1).getUpdateTime();

                                        if (endDate.getTime() - startTmp.getTime() >= time) {
                                            start = sDateFormat.format(startTmp);
                                            end = sDateFormat.format(endDate);
                                            dt.add(start + "至" + end);
                                        }

                                    }
                                } else {
                                    String endTimes = sDateFormatY.format(comInformations.get(i).getUpdateTime()) + " 23:59:59";
                                    Date endDate = null;
                                    try {
                                        endDate = sDateFormat.parse(endTimes);
                                    } catch (ParseException e) {
                                        e.printStackTrace();
                                    }
                                    if (endDate.getTime() - startTmp.getTime() >= time) {
                                        dt.add(start + "至" + endTimes);
                                    }
                                }
                            } else {
                                end = sDateFormatY.format(comInformations.get(i).getUpdateTime()) + " 23:59:59";
                                Date endDate = null;
                                try {
                                    endDate = sDateFormat.parse(end);
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                                if (endDate.getTime() - startTmp.getTime() >= time) {
                                    dt.add(start + "至" + end);
                                }
                            }
                        }
                    }
                    if (dt.size() > 0) {
                        DevMsgInfo devMsgInfo = new DevMsgInfo();
                        devMsgInfo.setDevIndex(devIndex);
                        devMsgInfo.setOffCount(dt.size());
                        devMsgInfo.setOffDesc(dt);
                        offMap.put(devIndex, devMsgInfo);
                    }
                }


            }

        }
        //对在线率为0的装置默认中断时长为一天



        List<TopExceptionParam> devZero = topStrategyMapper.getDevOnlineZero(startTime);
        if (CollectionUtil.isNotEmpty(devZero)) {
            for (TopExceptionParam param : devZero) {
                List<String> zeroOnline = new ArrayList<>();
                String timeStr = sdf.format(param.getNormalTime()) + "至" + sdf.format(endTime);
                zeroOnline.add(timeStr);
                DevMsgInfo devMsgInfo = new DevMsgInfo();
                devMsgInfo.setDevIndex(param.getDevIndex());
                devMsgInfo.setOffCount(1);
                devMsgInfo.setOffDesc(zeroOnline);
                offMap.put(param.getDevIndex(), devMsgInfo);
            }
        }
        //流量


        SimpleDateFormat ss = new SimpleDateFormat("yyyy-MM");
        String timeId = ss.format(startTime);
        List<TopExceptionParam> flowList = topStrategyMapper.getFlowOutTask(startTime, timeId, 90, lastDay, days);


        //汇总

        List<TopException> topList = new ArrayList<>();
        if (alarmMap.size() > 0) {
            Iterator<Map.Entry<Integer, DevMsgInfo>> it = alarmMap.entrySet().iterator();
            while (it.hasNext()) {
                StringBuilder stringBuilder = new StringBuilder();
                Map.Entry<Integer, DevMsgInfo> entry = it.next();
                List<String> strList = entry.getValue().getAlarmDesc();
                if (CollectionUtil.isNotEmpty(strList)) {
                    for (int i = 0; i < strList.size(); i++) {
                        if (i == strList.size() - 1) {
                            stringBuilder.append(strList.get(i));
                        } else {
                            stringBuilder.append(strList.get(i)).append(";");
                        }

                    }
                }
                TopException topException = new TopException();
                topException.setDevIndex(entry.getKey());
                topException.setAlarmNum(entry.getValue().getAlarmCount());
                topException.setComoutNum(0);
                topException.setAlarmDesc(stringBuilder.toString());
                topException.setState(1);
                topException.setOverLimit(0);
                topException.setTimeId(startTime);
                topException.setMsgIndex(UUID.randomUUID().toString());
                topException.setFlowStand(0);
                topException.setFlowNum((float) 0);
                topException.setLimitValue((float) 0);
                topList.add(topException);
            }
        }
        //数据完整性
        List<TopException> topListTwo = new ArrayList<>();
        if (inteList.size() != 0) {
            Iterator<Map.Entry<Integer, Float>> iterator = inteList.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<Integer, Float> entry = iterator.next();
                Integer devIndex = entry.getKey();
                float inte = entry.getValue();

                boolean flag = false;
                for (TopException topException : topList) {
                    if (topException.getDevIndex().equals(devIndex)) {
                        topException.setOverLimit(1);
                        topException.setLimitValue(inte);
                        flag = true;
                        break;
                    } else {
                        flag = false;
                    }
                }
                if (!flag) {
                    TopException topException = new TopException();
                    topException.setDevIndex(devIndex);
                    topException.setOverLimit(1);
                    topException.setAlarmNum(0);
                    topException.setComoutNum(0);
                    topException.setState(1);
                    topException.setTimeId(startTime);
                    topException.setMsgIndex(UUID.randomUUID().toString());
                    topException.setFlowStand(0);
                    topException.setFlowNum((float) 0);
                    topException.setLimitValue(inte);
                    topListTwo.add(topException);
                }
            }

            topList.addAll(topListTwo);

        }

        //持续中断时长
        if (offMap.size() != 0) {
            Iterator<Map.Entry<Integer, DevMsgInfo>> it = offMap.entrySet().iterator();


            List<TopException> listThree = new ArrayList<>();

            while (it.hasNext()) {
                StringBuilder stringBuilder = new StringBuilder();
                Map.Entry<Integer, DevMsgInfo> entry = it.next();
                List<String> offList = entry.getValue().getOffDesc();
                if (CollectionUtil.isNotEmpty(offList)) {
                    for (int i = 0; i < offList.size(); i++) {
                        if (i == offList.size() - 1) {
                            stringBuilder.append(offList.get(i));
                        } else {
                            stringBuilder.append(offList.get(i)).append(";");
                        }

                    }
                }
                boolean flag = false;
                for (TopException topException : topList) {
                    if (entry.getKey().equals(topException.getDevIndex())) {
                        topException.setComoutNum(entry.getValue().getOffCount());
                        topException.setComoutDesc(stringBuilder.toString());
                        flag = true;
                        break;
                    } else {
                        flag = false;
                    }
                }
                if (!flag) {
                    TopException topException = new TopException();
                    topException.setComoutDesc(stringBuilder.toString());
                    topException.setAlarmNum(0);
                    topException.setDevIndex(entry.getKey());
                    topException.setComoutNum(entry.getValue().getOffCount());
                    topException.setOverLimit(0);
                    topException.setState(1);
                    topException.setTimeId(startTime);
                    topException.setMsgIndex(UUID.randomUUID().toString());
                    topException.setFlowStand(0);
                    topException.setFlowNum((float) 0);
                    topException.setLimitValue((float) 0);
                    listThree.add(topException);
                }

            }
            topList.addAll(listThree);
        }


        List<TopException> listFour = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(flowList)) {
            for (TopExceptionParam topExceptionParam : flowList) {
                boolean flag = false;
                for (TopException topException : topList) {
                    if (topException.getDevIndex().equals(topExceptionParam.getDevIndex())) {
                        topException.setFlowNum(topExceptionParam.getFlowRate());
                        topException.setFlowStand(1);
                        flag = true;
                        break;
                    } else {
                        flag = false;
                    }
                }
                if (!flag) {
                    TopException topException = new TopException();
                    topException.setDevIndex(topExceptionParam.getDevIndex());
                    topException.setOverLimit(0);
                    topException.setAlarmNum(0);
                    topException.setComoutNum(0);
                    topException.setState(1);
                    topException.setTimeId(startTime);
                    topException.setFlowStand(1);
                    topException.setFlowNum(topExceptionParam.getFlowRate());
                    topException.setMsgIndex(UUID.randomUUID().toString());
                    topException.setLimitValue((float) 0);
                    listFour.add(topException);
                }
            }
            topList.addAll(listFour);
        }

        if (CollectionUtil.isNotEmpty(topList)) {

            //入库操作
            Integer res = topStrategyMapper.addTopException(topList);
            if (res > 0) {
                //进行流量查询
                List<TopExceptionParam> flowDevList = topStrategyMapper.getDevFlow(startTime, timeId);
                if (CollectionUtil.isNotEmpty(flowDevList)) {
                    topStrategyMapper.batchUpdateDevFlow(flowDevList);


                }
            }
        }

        long bb = System.currentTimeMillis();
        System.out.println("执行时间" + (bb - aa) / 1000);

    }

    /**
     * 统计每日终端在线率
     *
     * @author cdf
     * @date 2021/12/16
     */
    public void runRateDay() {
        long aa = System.currentTimeMillis();
        System.out.println("开始执行++++++++++++++++++++++++++");

        Date[] dates = getYesterday();
        Date startTime = dates[0];
        Date endTime = dates[1];

        /*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime = null;
        Date endTime = null;
        try {
            startTime = sdf.parse("2021-12-11 00:00:00");
            endTime = sdf.parse("2021-12-11 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }*/

        Integer res = onlineRateCldMapper.getOnlineCount(startTime);
        if(res>0){
            logger.error(startTime + "runRateDay数据已经存在,是否存在重复运行环境!");
            return;
        }

        List<OnlineRateCld> cldList = new ArrayList<>();
        List<Integer> devAll = new ArrayList<>();
        List<Integer> comList = new ArrayList<>();

        List<TopExceptionParam> devListAll = onlineRateCldMapper.getRunDevList();
        if (CollectionUtil.isNotEmpty(devListAll)) {
            devAll = devListAll.stream().map(TopExceptionParam::getDevIndex).collect(Collectors.toList());
        }
        List<TopExceptionParam> devList = topStrategyMapper.getOffLineTask(startTime, endTime);
        if (CollectionUtil.isNotEmpty(devList)) {
            comList = devList.stream().map(TopExceptionParam::getDevIndex).collect(Collectors.toList());
            devAll.removeAll(comList);
            //获取告警策略
            Map<Integer, TerminalRun> hashMap = getTopStrategyList();
            if (Objects.isNull(hashMap)) {
                logger.error(new Date() + "终端运行异常判断策略标准为空,请先配置! 方法名TopExceptionTask");
                return;
            }

            for (TopExceptionParam device : devList) {
                int offCount = 0; //中断次数
                int offTime = 0;

                Integer devIndex = device.getDevIndex();

                int time = 3600000;
                if (Objects.isNull(device.getParamIndex())) {
                    device.setParamIndex(3);
                }
                Integer lineGrade = device.getParamIndex();

                if (hashMap.containsKey(lineGrade)) {
                    time = hashMap.get(lineGrade).getOfftimeValue() * 60;
                } else {
                    logger.error("终端运行异常判断策略标准缺失,请先配置! 方法名TopExceptionTask");
                    return;
                }

                List<OnlineRateCldParam> comInformations = topStrategyMapper.getOffTimeTask(startTime, endTime, devIndex);
                //判断cominfomation表是否存在数据，不存在数据分两种情况 0.一整天都是中断 1.一整天都通讯正常
                if (CollectionUtil.isNotEmpty(comInformations)) {

                    for (int i = 0; i < comInformations.size(); i++) {
                        if (comInformations.size() > 1) {
                            if (comInformations.get(i).getType() == 0) {
                                if (i == 0) {
                                    //中断
                                    int interval = (int) (endTime.getTime() - comInformations.get(i).getUpdateTime().getTime()) / 1000;
                                    offTime += interval;
                                    if (interval > time) {
                                        offCount++;
                                    }
                                }
                            } else {
                                if (i == comInformations.size() - 1) {
                                    //正常
                                    int interval = (int) (comInformations.get(i).getUpdateTime().getTime() - startTime.getTime()) / 1000;
                                    offTime += interval;
                                    if (interval > time) {
                                        offCount++;
                                    }
                                } else {
                                    offTime += comInformations.get(i).getDiff();
                                    if (comInformations.get(i).getDiff() > time) {
                                        offCount++;
                                    }
                                }
                            }
                        } else {
                            if (comInformations.get(i).getType() == 0) {
                                //中断
                                int interval = (int) (endTime.getTime() - comInformations.get(i).getUpdateTime().getTime()) / 1000;
                                offTime += interval;
                                if (interval > time) {
                                    offCount++;
                                }
                            } else {
                                //正常
                                int interval = (int) (comInformations.get(i).getUpdateTime().getTime() - startTime.getTime()) / 1000;
                                offTime += interval;
                                if (interval > time) {
                                    offCount++;
                                }
                            }
                        }
                    }

                    OnlineRateCld onlineRateCld = new OnlineRateCld();
                    onlineRateCld.setDevIndex(devIndex);
                    onlineRateCld.setOffCount(offCount);
                    onlineRateCld.setOnlineRate(((dayTime-offTime) / dayTime)*100);
                    onlineRateCld.setTimeId(startTime);
                    cldList.add(onlineRateCld);
                }
            }
        }

        if (CollectionUtil.isNotEmpty(devAll)) {
            List<OnlineRateCldParam> zeroList = onlineRateCldMapper.getOnlineByDevIndex(startTime, devAll);
            if (CollectionUtil.isNotEmpty(zeroList)) {
                for (OnlineRateCldParam onlineRateCldParam : zeroList) {
                    OnlineRateCld onlineRateCld = new OnlineRateCld();
                    onlineRateCld.setDevIndex(onlineRateCldParam.getDevIndex());
                    onlineRateCld.setTimeId(startTime);
                    if (onlineRateCldParam.getOfflineMin() == 0) {
                        onlineRateCld.setOffCount(0);
                        onlineRateCld.setOnlineRate(100f);
                    } else {
                        onlineRateCld.setOffCount(1);
                        onlineRateCld.setOnlineRate(0f);
                    }
                    cldList.add(onlineRateCld);
                }
            }
        }
        if(CollectionUtil.isNotEmpty(cldList)){
            onlineRateCldMapper.batchAdd(cldList);
        }
        long bb = System.currentTimeMillis();
        System.out.println((bb - aa) / 1000);
    }


    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        try {
             runTask();
        } catch (Exception e) {
            logger.error(e.toString() + "___" + e.getMessage());
        }

        try {
            runRateDay();
        } catch (Exception e) {
            logger.error(e.toString() + "___" + e.getMessage());
        }

    }


    /**
     * 获取昨天起始时间和结束时间
     *
     * @author cdf
     * @date 2021/12/16
     */
    private Date[] getYesterday() {
        Date[] dates = new Date[2];
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startTime = calendar.getTime();
        dates[0] = startTime;

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endTime = calendar.getTime();
        dates[1] = endTime;
        return dates;
    }

    /**
     * 获取告警策略
     *
     * @author cdf
     * @date 2021/12/16
     */
    public Map<Integer, TerminalRun> getTopStrategyList() {
        List<TerminalRun> strategyList = topStrategyMapper.getList();
        if (CollectionUtil.isEmpty(strategyList)) {
            return null;
        } else {
            HashMap<Integer, TerminalRun> hashMap = new HashMap();
            for (TerminalRun terminalRun : strategyList) {
                hashMap.put(terminalRun.getDicLeave(), terminalRun);
            }
            return hashMap;
        }
    }


}
