package com.gyee.alarm.task.thread;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyee.common.contant.ContantXk;
import com.gyee.common.model.PointData;
import com.gyee.alarm.init.CacheContext;
import com.gyee.alarm.model.auto.*;
import com.gyee.alarm.model.vo.StatData;
import com.gyee.alarm.service.auto.*;
import com.gyee.alarm.util.DateUtils;
import com.gyee.alarm.util.StringUtils;
import com.gyee.alarm.util.realtimesource.IEdosUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.Callable;

public class MainBrownoutsThreadPool implements Callable<String>, Serializable {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final long serialVersionUID = 0;

    // 保存任务所需要的数据

    private Object threadPoolTaskData;
    private Map<String, List<PointData>> wpstatusMap;

    private String wpId;
    private Map<String, ProEconMainBrownouts> oldMainBrownoutsMap;
    private Map<String, ProEconMainBrownouts2> oldMainBrownouts2Map;

    private IProEconMainBrownoutsService proEconMainBrownoutsService;

    private Map<String, Map<String, ProEconMainBrownouts>> newMainBrownoutsMap;
    private Map<String, Map<String, ProEconMainBrownouts2>> newMainBrownouts2Map;

    private IProEconMainBrownouts2Service proEconMainBrownouts2Service;
    private IEdosUtil edosUtil;
    private Date begin;
    private Date end;


    public MainBrownoutsThreadPool(Object tasks, Map<String, List<PointData>> wpstatusMap, String wpId, Map<String, ProEconMainBrownouts> oldMainBrownoutsMap, Map<String, ProEconMainBrownouts2> oldMainBrownouts2Map, IProEconMainBrownoutsService proEconMainBrownoutsService, Map<String, Map<String, ProEconMainBrownouts>> newMainBrownoutsMap, Map<String, Map<String, ProEconMainBrownouts2>> newMainBrownouts2Map, IProEconMainBrownouts2Service proEconMainBrownouts2Service, IEdosUtil edosUtil, Date begin, Date end

    ) {

        this.threadPoolTaskData = tasks;
        this.wpstatusMap = wpstatusMap;
        this.wpId = wpId;
        this.oldMainBrownoutsMap = oldMainBrownoutsMap;
        this.oldMainBrownouts2Map = oldMainBrownouts2Map;
        this.proEconMainBrownoutsService = proEconMainBrownoutsService;
        this.newMainBrownoutsMap = newMainBrownoutsMap;
        this.newMainBrownouts2Map = newMainBrownouts2Map;
        this.begin = begin;
        this.end = end;

        this.edosUtil = edosUtil;
        this.proEconMainBrownouts2Service = proEconMainBrownouts2Service;

    }

    public synchronized String call() throws Exception {


        // 处理一个任务，这里的处理方式太简单了，仅仅是一个打印语句

        //System.out.println("开始执行任务：" + threadPoolTaskData);

        String result = "";

        // //便于观察，等待一段时间


        try {

            List<ProEconMainBrownouts2> proEconMainBrownouts2ls=new ArrayList<>();
            List<ProEconMainBrownouts> proEconMainBrownoutsls=new ArrayList<>();
            Map<String, ProBasicPowerstationPoint> wppointmap = CacheContext.wppointmap.get(wpId);

            //取实时状态数据 赋值给status

            if (wppointmap.containsKey(ContantXk.CZZT)) {
                ProBasicPowerstationPoint mxztPoint = wppointmap.get(ContantXk.CZZT);
                //获取5分钟没个间隔1秒钟，保证状态与时序库保持一致
                List<PointData> statusls = edosUtil.getHistoryDatasSnap(mxztPoint.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000, null, 1L);
                wpstatusMap.put(wpId, statusls);
            }

            ProEconMainBrownouts mainBrownouts = null;
            ProEconMainBrownouts2 mainBrownouts2;
            //获取5分钟的状态值
            List<PointData> statusls = wpstatusMap.get(wpId);

            //记录上次判定的状态值
            int lastStatus = (int) statusls.get(0).getPointValueInDouble();
            for (PointData stpo : statusls) {

                //获取当前状态
                int currentStatus = (int) stpo.getPointValueInDouble();
                //获取当前时间
                Date currentTime = new Date(stpo.getPointTime());
                //如果数据库中不存在该风机未完成的故障记录，进入
                if (mainBrownouts == null) {
                    if (currentStatus == 4) {
                        mainBrownouts = new ProEconMainBrownouts();

                        intialainBrownouts(wpId, wppointmap, currentTime, mainBrownouts);

                        oldMainBrownoutsMap.put(wpId, mainBrownouts);


                        mainBrownouts2 = new ProEconMainBrownouts2();
                        intialainBrownouts2(wpId, wppointmap, currentTime, mainBrownouts2);
                        oldMainBrownouts2Map.put(wpId, mainBrownouts2);
                    }


                    //将当前状态赋值给过去状态
                    lastStatus = currentStatus;
                } else if (lastStatus != currentStatus) {

                    //如果添加了状态值，状态值变化存储，并清空
                    if (oldMainBrownoutsMap.containsKey(wpId)) {

                        //获取数据库中的状态值，状态值变化存储，并清空
                        mainBrownouts = oldMainBrownoutsMap.get(wpId);
                        if (mainBrownouts == null) {
                            mainBrownouts = new ProEconMainBrownouts();
                            intialainBrownouts(wpId, wppointmap, currentTime, mainBrownouts);
                            oldMainBrownoutsMap.put(wpId, mainBrownouts);

                        } else {
                            finishMainBrownouts(proEconMainBrownoutsls,wpId, mainBrownouts, currentTime);
                            oldMainBrownoutsMap.put(wpId, null);
                            mainBrownouts = null;
                        }


                    }

                    if (oldMainBrownouts2Map.containsKey(wpId)) {

                        //获取数据库中的状态值，状态值变化存储，并清空
                        mainBrownouts2 = oldMainBrownouts2Map.get(wpId);
                        if (mainBrownouts2 == null) {
                            mainBrownouts2 = new ProEconMainBrownouts2();
                            intialainBrownouts2(wpId, wppointmap, currentTime, mainBrownouts2);
                            oldMainBrownouts2Map.put(wpId, mainBrownouts2);
                        } else {
                            finishMainBrownouts2(proEconMainBrownouts2ls,wpId, mainBrownouts2, currentTime);
                            oldMainBrownouts2Map.put(wpId, null);
                        }


                    }


                    lastStatus = currentStatus;
                }

            }
            //循环结束落盘，并清空
            if (oldMainBrownoutsMap.containsKey(wpId)) {
                //获取数据库查询是否有风机对应时间的记录，如果没有写入数据库
                mainBrownouts = oldMainBrownoutsMap.get(wpId);

                if (mainBrownouts != null) {
                    ProEconMainBrownouts finalItem = mainBrownouts;
                    QueryWrapper<ProEconMainBrownouts> queryWrapper5 = new QueryWrapper<>();
                    queryWrapper5.eq("windpowerstation_id", finalItem.getWindpowerstationId()).eq("stop_Time", finalItem.getStopTime());
                    List<ProEconMainBrownouts> ls = proEconMainBrownoutsService.list(queryWrapper5);
//                            .stream()
//                            .filter(i -> i.getWindpowerstationId().equals(finalItem.getWindpowerstationId())
//                                    && i.getStopTime().compareTo(finalItem.getStopTime()) == 0)
                    //.collect(Collectors.toList());
//
                    if (ls.isEmpty()) {

                        proEconMainBrownoutsls.add(finalItem);
                       // proEconMainBrownoutsService.save(finalItem);
                        oldMainBrownoutsMap.put(wpId, null);

                        if (newMainBrownoutsMap.containsKey(wpId)) {
                            Map<String, ProEconMainBrownouts> mbmap = newMainBrownoutsMap.get(wpId);
                            mbmap.put(String.valueOf(mainBrownouts.getStopTime().getTime()), mainBrownouts);
                        } else {
                            Map<String, ProEconMainBrownouts> mbmap = new HashMap<>();
                            mbmap.put(String.valueOf(mainBrownouts.getStopTime().getTime()), mainBrownouts);
                            newMainBrownoutsMap.put(wpId, mbmap);
                        }
                    }
                }


            }


            if (oldMainBrownouts2Map.containsKey(wpId)) {
                //获取数据库查询是否有风机对应时间的记录，如果没有写入数据库
                mainBrownouts2 = oldMainBrownouts2Map.get(wpId);
                if (mainBrownouts2 != null) {
                    ProEconMainBrownouts2 finalItem = mainBrownouts2;
                    QueryWrapper<ProEconMainBrownouts2> queryWrapper5 = new QueryWrapper<>();
                    queryWrapper5.eq("windpowerstation_id", finalItem.getWindpowerstationId()).eq("stop_Time", finalItem.getStopTime());
                    List<ProEconMainBrownouts2> ls = proEconMainBrownouts2Service.list(queryWrapper5);
//                            .stream().filter(i -> i.getWindpowerstationId().equals(finalItem.getWindpowerstationId())
//                                    && i.getStopTime().compareTo(finalItem.getStopTime()) == 0).collect(Collectors.toList());

                    if (ls.isEmpty()) {
                        proEconMainBrownouts2ls.add(finalItem);
                       // proEconMainBrownouts2Service.save(finalItem);
                        oldMainBrownouts2Map.put(wpId, null);

                        if (newMainBrownouts2Map.containsKey(wpId)) {
                            Map<String, ProEconMainBrownouts2> mbmap = newMainBrownouts2Map.get(wpId);
                            mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
                        } else {
                            Map<String, ProEconMainBrownouts2> mbmap = new HashMap<>();
                            mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
                            newMainBrownouts2Map.put(wpId, mbmap);
                        }
                    }

                }

            }

            List<ProEconMainBrownouts> templs=new ArrayList<>();
            for(ProEconMainBrownouts vo:proEconMainBrownoutsls)
            {
                templs.add(vo);
                if(templs.size()==100)
                {
                    proEconMainBrownoutsService.saveOrUpdateBatch(templs);
                    templs=new ArrayList<>();
                }
            }

            if(!templs.isEmpty())
            {
                proEconMainBrownoutsService.saveOrUpdateBatch(templs);
            }


            List<ProEconMainBrownouts2> templs2=new ArrayList<>();
            for(ProEconMainBrownouts2 vo:proEconMainBrownouts2ls)
            {
                templs2.add(vo);
                if(templs2.size()==100)
                {
                    proEconMainBrownouts2Service.saveOrUpdateBatch(templs2);
                    templs2=new ArrayList<>();
                }
            }

            if(!templs2.isEmpty())
            {
                proEconMainBrownouts2Service.saveOrUpdateBatch(templs2);
            }
//            proEconMainBrownoutsService.saveOrUpdateBatch(proEconMainBrownoutsls);
//            proEconMainBrownouts2Service.saveOrUpdateBatch(proEconMainBrownouts2ls);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        threadPoolTaskData = null;

        return result;

    }

    private void intialainBrownouts2(String wpId, Map<String, ProBasicPowerstationPoint> wppointmap, Date currentTime, ProEconMainBrownouts2 mainBrownouts2) throws Exception {
        PointData data;
        long pried;
        List<PointData> hsls;
        mainBrownouts2.setId(StringUtils.getUUID());
        mainBrownouts2.setStopTime(currentTime);
        mainBrownouts2.setStartTime(null);
        mainBrownouts2.setStopTypeId("限电");
        data = edosUtil.getRealData(wppointmap.get(ContantXk.SSZGL));
        mainBrownouts2.setLimitLoad(StringUtils.round(data.getPointValueInDouble(), 2));
        data = edosUtil.getRealData(wppointmap.get(ContantXk.SSPJFS));
        mainBrownouts2.setWindSpeed(StringUtils.round(data.getPointValueInDouble(), 2));


        pried = DateUtils.secondsDiff(DateUtils.addMinutes(currentTime, -5), currentTime);
        hsls = edosUtil.getHistStat(wppointmap.get(ContantXk.SSZGL), DateUtils.addMinutes(currentTime, -5).getTime() / 1000, currentTime.getTime() / 1000, 1L, pried, StatData.MAX.getValue());
        if (StringUtils.notEmp(hsls) && hsls.size() > 0) {
            mainBrownouts2.setThisLoad(hsls.get(0).getPointValueInDouble());

        }

        mainBrownouts2.setWindpowerstationId(wpId);
        mainBrownouts2.setLossPower(0.0);
    }

    private void intialainBrownouts(String wpId, Map<String, ProBasicPowerstationPoint> wppointmap, Date currentTime, ProEconMainBrownouts mainBrownouts) throws Exception {


        mainBrownouts.setId(StringUtils.getUUID());
        mainBrownouts.setStopTime(currentTime);
        mainBrownouts.setStartTime(null);
        mainBrownouts.setStopTypeId("限电");
        PointData data = edosUtil.getRealData(wppointmap.get(ContantXk.SSZGL));
        mainBrownouts.setLimitLoad(StringUtils.round(data.getPointValueInDouble(), 2));
        data = edosUtil.getRealData(wppointmap.get(ContantXk.SSPJFS));
        mainBrownouts.setWindSpeed(StringUtils.round(data.getPointValueInDouble(), 2));


        long pried = DateUtils.secondsDiff(DateUtils.addMinutes(currentTime, -5), currentTime);
        List<PointData> hsls = edosUtil.getHistStat(wppointmap.get(ContantXk.SSZGL), DateUtils.addMinutes(currentTime, -5).getTime() / 1000, currentTime.getTime() / 1000, 1L, pried, StatData.MAX.getValue());
        if (StringUtils.notEmp(hsls) && hsls.size() > 0) {
            mainBrownouts.setThisLoad(hsls.get(0).getPointValueInDouble());

        }
        mainBrownouts.setWindpowerstationId(wpId);
        mainBrownouts.setLossPower(0.0);
    }


    private void finishMainBrownouts2(List<ProEconMainBrownouts2> proEconMainBrownouts2ls,String wpId, ProEconMainBrownouts2 mainBrownouts2, Date currentTime) throws Exception {
//        if(currentStatus != 4 )
//        {
        mainBrownouts2.setStartTime(currentTime);

        double timehour = DateUtils.hoursDiff2(mainBrownouts2.getStartTime(), mainBrownouts2.getStopTime());
        mainBrownouts2.setStopHours(timehour);
        double losspower = calWpLossPower(wpId, mainBrownouts2.getStartTime(), mainBrownouts2.getStopTime());
        mainBrownouts2.setLossPower(losspower);

        if (timehour <= 24) {
            //proEconMainBrownouts2Service.saveOrUpdate(mainBrownouts2);
            proEconMainBrownouts2ls.add(mainBrownouts2);
            if (newMainBrownouts2Map.containsKey(wpId)) {
                Map<String, ProEconMainBrownouts2> mbmap = newMainBrownouts2Map.get(wpId);
                mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
            } else {
                Map<String, ProEconMainBrownouts2> mbmap = new HashMap<>();
                mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
                newMainBrownouts2Map.put(wpId, mbmap);
            }
        } else {
            int days = DateUtils.daysDiff1(mainBrownouts2.getStartTime(), mainBrownouts2.getStopTime());
            Calendar c = Calendar.getInstance();
            Date startTime = mainBrownouts2.getStartTime();
            c.setTime(mainBrownouts2.getStopTime());
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
            for (int i = 0; i < days; i++) {
                if (i == 0) {
                    mainBrownouts2.setStartTime(c.getTime());
                    losspower = calWpLossPower(wpId, mainBrownouts2.getStartTime(), mainBrownouts2.getStopTime());

                } else {
                    mainBrownouts2.setStopTime(DateUtils.truncate(c.getTime()));
                    if (i == days - 1) {
                        mainBrownouts2.setStartTime(startTime);

                    } else {
                        mainBrownouts2.setStartTime(c.getTime());

                    }
                    losspower = calWpLossPower(wpId, mainBrownouts2.getStartTime(), mainBrownouts2.getStopTime());
                }
                mainBrownouts2.setLossPower(losspower);
                //proEconMainBrownouts2Service.saveOrUpdate(mainBrownouts2);
                proEconMainBrownouts2ls.add(mainBrownouts2);
                if (newMainBrownouts2Map.containsKey(wpId)) {
                    Map<String, ProEconMainBrownouts2> mbmap = newMainBrownouts2Map.get(wpId);
                    mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
                } else {
                    Map<String, ProEconMainBrownouts2> mbmap = new HashMap<>();
                    mbmap.put(String.valueOf(mainBrownouts2.getStopTime().getTime()), mainBrownouts2);
                    newMainBrownouts2Map.put(wpId, mbmap);
                }

                c.add(Calendar.DAY_OF_MONTH, 1);
            }
        }


//        }

    }

    private void finishMainBrownouts(List<ProEconMainBrownouts> proEconMainBrownoutsls,String wpId, ProEconMainBrownouts item, Date currentTime) throws Exception {
//        if(currentStatus != 4 )
//        {
        item.setStartTime(currentTime);
        double timehour = DateUtils.hoursDiff2(item.getStartTime(), item.getStopTime());
        item.setStopHours(timehour);
        double losspower = calWpLossPower(wpId, item.getStartTime(), item.getStopTime());
        item.setLossPower(losspower);
       // proEconMainBrownoutsService.saveOrUpdate(item);
        proEconMainBrownoutsls.add(item);
        if (newMainBrownoutsMap.containsKey(wpId)) {
            Map<String, ProEconMainBrownouts> mbmap = newMainBrownoutsMap.get(wpId);
            mbmap.put(String.valueOf(item.getStopTime().getTime()), item);
        } else {
            Map<String, ProEconMainBrownouts> mbmap = new HashMap<>();
            mbmap.put(String.valueOf(item.getStopTime().getTime()), item);
            newMainBrownoutsMap.put(wpId, mbmap);
        }
//        }
    }

    //修改后的限电损失统计，通过时序数据库历史切面计算
    private Double calWpLossPower(String wpId, Date startDate, Date endDate) throws Exception {
        double result = 0.0;

        Map<String, Map<String, ProBasicPowerstationPoint>> wppointmap = CacheContext.wppointmap;
        Map<String, ProBasicPowerstationPoint> wtpointmap = wppointmap.get(wpId);

        Calendar c1 = Calendar.getInstance();
        c1.setTime(startDate);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(endDate);
        //判定限电是否跨年
        if (endDate.after(startDate) && c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)) {
            //年限电欠发损失电量
            if (wtpointmap.containsKey(ContantXk.NXDTJSSDL)) {
                double beginvalue;
                double endvalue;


                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDTJSSDL).getNemCode());
                List<PointData> xdbegin = edosUtil.getHistMatrix(pointid, startDate.getTime() / 1000);
                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endDate.getTime() / 1000);


                if (xdbegin.size() == 1 && xdend.size() == 1) {
                    beginvalue = xdbegin.get(0).getPointValueInDouble();
                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > beginvalue) {
                        result = result + (endvalue - beginvalue);
                    }
                }
            }

            //年限电损失电量
            if (wtpointmap.containsKey(ContantXk.NXDJCLSSDL)) {
                double beginvalue;
                double endvalue;

                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDJCLSSDL).getNemCode());
                List<PointData> xdbegin = edosUtil.getHistMatrix(pointid, startDate.getTime() / 1000);
                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endDate.getTime() / 1000);


                if (xdbegin.size() == 1 && xdend.size() == 1) {
                    beginvalue = xdbegin.get(0).getPointValueInDouble();
                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > beginvalue) {
                        result = result + (endvalue - beginvalue);
                    }
                }
            }
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(DateUtils.truncate(startDate));
            c.add(Calendar.DAY_OF_MONTH, 1);
            //获得1月1日零点值
            Date endtime = c.getTime();
            //年限电欠发损失电量
            if (wtpointmap.containsKey(ContantXk.NXDTJSSDL)) {
                double beginvalue;
                double endvalue;

                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDTJSSDL).getNemCode());
                List<PointData> xdbegin = edosUtil.getHistMatrix(pointid, startDate.getTime() / 1000);
                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endtime.getTime() / 1000);


                if (xdbegin.size() == 1 && xdend.size() == 1) {
                    beginvalue = xdbegin.get(0).getPointValueInDouble();
                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > beginvalue) {
                        result = result + (endvalue - beginvalue);
                    }
                }
            }

            //年限电损失电量
            if (wtpointmap.containsKey(ContantXk.NXDJCLSSDL)) {
                double beginvalue;
                double endvalue;

                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDJCLSSDL).getNemCode());
                List<PointData> xdbegin = edosUtil.getHistMatrix(pointid, startDate.getTime() / 1000);
                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endtime.getTime() / 1000);


                if (xdbegin.size() == 1 && xdend.size() == 1) {
                    beginvalue = xdbegin.get(0).getPointValueInDouble();
                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > beginvalue) {
                        result = result + (endvalue - beginvalue);
                    }
                }
            }


            //日限电欠发损失电量
            if (wtpointmap.containsKey(ContantXk.NXDTJSSDL)) {

                double endvalue;


                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDTJSSDL).getNemCode());

                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endDate.getTime() / 1000);


                if (xdend.size() == 1) {

                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > 0) {
                        result = result + endvalue;
                    }
                }
            }

            //日限电损失电量
            if (wtpointmap.containsKey(ContantXk.NXDJCLSSDL)) {

                double endvalue;


                List<String> pointid = new ArrayList<>();
                pointid.add(wtpointmap.get(ContantXk.NXDJCLSSDL).getNemCode());

                List<PointData> xdend = edosUtil.getHistMatrix(pointid, endDate.getTime() / 1000);


                if (xdend.size() == 1) {

                    endvalue = xdend.get(0).getPointValueInDouble();

                    if (endvalue > 0) {
                        result = result + endvalue;
                    }
                }
            }
        }


        return result;

    }
}