package com.gyee.generation.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyee.common.model.PointData;
import com.gyee.generation.init.CacheContext;
import com.gyee.generation.model.auto.*;
import com.gyee.generation.service.auto.IProEconBrownoutsEvent2Service;
import com.gyee.generation.service.auto.IProEconBrownoutsEventService;
import com.gyee.generation.service.auto.IProEconMainBrownouts2Service;
import com.gyee.generation.service.auto.IProEconMainBrownoutsService;
import com.gyee.generation.task.thread.BrownoutsThread;
import com.gyee.generation.task.thread.MainBrownoutsThread;
import com.gyee.generation.util.DateUtils;
import com.gyee.generation.util.realtimesource.IEdosUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

@Service
public class LimitEventService {


    @Resource
    private IProEconBrownoutsEventService proEconBrownoutsEventService;

    @Resource
    private IProEconMainBrownoutsService proEconMainBrownoutsService;

    @Resource
    private IProEconBrownoutsEvent2Service proEconBrownoutsEvent2Service;

    @Resource
    private IProEconMainBrownouts2Service proEconMainBrownouts2Service;


    @Resource
    private IEdosUtil edosUtil;

    @Resource
    @Qualifier("applicationTaskExecutor")
    private Executor executor;
    @Resource
    @Qualifier("applicationTaskExecutor")
    private Executor mainexecutor;

    @Value("${frequency.powerrationing}")
    private Integer frequency;
    public static Logger logger = LoggerFactory.getLogger(ShutdownnewService.class);
    /// 风机状态说明,key为状态码，value为状态说明
    public Map<Integer, String> statusDescriptionMap = new HashMap<>();
    /// 风机当前状态，key为风机编号
    public Map<String, List<PointData>> statusMap = new HashMap<>();
    public Map<String, List<PointData>> wpstatusMap = new HashMap<>();
    Map<String, ProEconBrownoutsEvent> oldBrownoutsStatusMap = new HashMap<>();

    Map<String, ProEconBrownoutsEvent2> oldBrownoutsStatus2Map = new HashMap<>();

    Map<String, ProEconMainBrownouts> oldMainBrownoutsMap = new HashMap<>();

    Map<String, ProEconMainBrownouts2> oldMainBrownouts2Map = new HashMap<>();

    public Map<String, Map<String, ProEconMainBrownouts>> newMainBrownoutsMap = new HashMap<>();

    public Map<String, Map<String, ProEconMainBrownouts2>> newMainBrownouts2Map = new HashMap<>();

    public void execBrownouts(Date recordDate) throws Exception {

        Date begin = DateUtils.addMinutes(recordDate, -frequency);


        Date end = recordDate;
        oldBrownoutsStatusMap.clear();
        oldBrownoutsStatus2Map.clear();

        statusDescriptionMap.put(0, "待机");
        statusDescriptionMap.put(1, "手动停机");
        statusDescriptionMap.put(2, "正常发电");
        statusDescriptionMap.put(3, "缺陷降出力");
        statusDescriptionMap.put(4, "故障停机");
        statusDescriptionMap.put(5, "故障受累");
        statusDescriptionMap.put(6, "检修停机");
        statusDescriptionMap.put(7, "检修受累");
        statusDescriptionMap.put(8, "限电降出力");
        statusDescriptionMap.put(9, "限电停机");
        statusDescriptionMap.put(10, "电网受累");
        statusDescriptionMap.put(11, "环境受累");
        statusDescriptionMap.put(12, "通讯中断");
        statusDescriptionMap.put(13, "设备离线");

        for (ProBasicPowerstation wp : CacheContext.wpls) {
            //            Map<String, ProBasicPowerstationPoint> wppointmap = CacheContext.wppointmap.get(wp.getId());
            //
            //            //取实时状态数据 赋值给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(wp.getId(), statusls);
            //            }
            wpstatusMap.put(wp.getId(), null);
            //初始化将所有风场编号作为key，value全部赋值为null
            oldMainBrownoutsMap.put(wp.getId(), null);
            oldMainBrownouts2Map.put(wp.getId(), null);

        }
        for (ProBasicEquipment wt : CacheContext.wtls) {
            //            Map<String, ProBasicEquipmentPoint> windturbinetestingpointnewMap = CacheContext.wtpAimap.get(wt.getId());
            //
            //            //取实时状态数据 赋值给status
            //
            //            if (windturbinetestingpointnewMap.containsKey(ContantXk.MXZT)) {
            //                ProBasicEquipmentPoint mxztPoint = windturbinetestingpointnewMap.get(ContantXk.MXZT);
            //                //获取5分钟没个间隔1秒钟，保证状态与时序库保持一致
            //                List<PointData> statusls = edosUtil.getHistoryDatasSnap(mxztPoint.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000, null, 1L);
            //                statusMap.put(wt.getId(), statusls);
            //            }
            statusMap.put(wt.getId(), null);
            //初始化将所有风机编号作为key，value全部赋值为null
            oldBrownoutsStatusMap.put(wt.getId(), null);
            oldBrownoutsStatus2Map.put(wt.getId(), null);

        }
        //******************************************************************************************************/

        //读取数据库存在的恢复时间为NULL的数据，并通过风机编号把数据遍历到对应的map

        QueryWrapper<ProEconMainBrownouts> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("start_Time");
        List<ProEconMainBrownouts> oldStatusQuery = proEconMainBrownoutsService.list(queryWrapper).stream()
                //                .filter(i -> StringUtils.empty(i.getStartTime()))
                .sorted(Comparator.comparing(ProEconMainBrownouts::getStopTime)).collect(Collectors.toList());

        for (ProEconMainBrownouts oldMainBrownouts : oldStatusQuery) {
            if (oldMainBrownoutsMap.containsKey(oldMainBrownouts.getWindpowerstationId())) {
                oldMainBrownoutsMap.put(oldMainBrownouts.getWindpowerstationId(), oldMainBrownouts);
            }
        }
        QueryWrapper<ProEconMainBrownouts2> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.isNull("start_Time");
        List<ProEconMainBrownouts2> oldStatus2Query = proEconMainBrownouts2Service.list(queryWrapper2).stream()
                //                .filter(i -> StringUtils.empty(i.getStartTime()))
                .sorted(Comparator.comparing(ProEconMainBrownouts2::getStopTime)).collect(Collectors.toList());

        for (ProEconMainBrownouts2 oldMainBrownouts2 : oldStatus2Query) {
            if (oldMainBrownouts2Map.containsKey(oldMainBrownouts2.getWindpowerstationId())) {
                oldMainBrownouts2Map.put(oldMainBrownouts2.getWindpowerstationId(), oldMainBrownouts2);
            }
        }
        QueryWrapper<ProEconBrownoutsEvent> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.isNull("start_Time");
        List<ProEconBrownoutsEvent> oldStatus3Query = proEconBrownoutsEventService.list(queryWrapper3).stream()
                //                .filter(i -> StringUtils.empty(i.getStartTime()))
                .sorted(Comparator.comparing(ProEconBrownoutsEvent::getStopTime)).collect(Collectors.toList());

        for (ProEconBrownoutsEvent oldBrownouts : oldStatus3Query) {
            if (oldBrownoutsStatusMap.containsKey(oldBrownouts.getWindturbineId())) {
                oldBrownoutsStatusMap.put(oldBrownouts.getWindturbineId(), oldBrownouts);
            }
        }
        QueryWrapper<ProEconBrownoutsEvent2> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.isNull("start_Time");
        List<ProEconBrownoutsEvent2> oldStatus4Query = proEconBrownoutsEvent2Service.list(queryWrapper4).stream()
                //                .filter(i -> StringUtils.empty(i.getStartTime()))
                .sorted(Comparator.comparing(ProEconBrownoutsEvent2::getStopTime)).collect(Collectors.toList());

        for (ProEconBrownoutsEvent2 oldBrownouts2 : oldStatus4Query) {
            if (oldBrownoutsStatus2Map.containsKey(oldBrownouts2.getWindturbineId())) {
                oldBrownoutsStatus2Map.put(oldBrownouts2.getWindturbineId(), oldBrownouts2);
            }
        }
        //*************************主表数据计算*****************************************************************************/


        final CountDownLatch latch = new CountDownLatch(oldMainBrownoutsMap.keySet().size());

        //遍历PG数据库中存在的记录，恢复时间为空的集合
        for (String wpId : oldMainBrownoutsMap.keySet()) {
            //
            //            new Thread(new MainBrownoutsThread(mainexecutor
            //                    ,  wpstatusMap,  wpId, oldMainBrownoutsMap, oldMainBrownouts2Map,  proEconMainBrownoutsService,  newMainBrownoutsMap,  newMainBrownouts2Map,  proEconMainBrownouts2Service,  edosUtil,  begin,  end)).start();
            //
            new Thread(new MainBrownoutsThread(mainexecutor
                    , wpstatusMap, wpId, oldMainBrownoutsMap, oldMainBrownouts2Map, proEconMainBrownoutsService, newMainBrownoutsMap, newMainBrownouts2Map, proEconMainBrownouts2Service, edosUtil, begin, end, latch)).start();

        }
        latch.await();
        //*************************主表数据计算*****************************************************************************/

        //*************************子表数据计算*****************************************************************************/
        //遍历PG数据库中存在的记录，恢复时间为空的集合
        for (String wtId : oldBrownoutsStatusMap.keySet()) {

            new Thread(new BrownoutsThread(executor,
                    statusMap, wtId, oldBrownoutsStatusMap, oldBrownoutsStatus2Map,
                    proEconBrownoutsEventService,
                    proEconBrownoutsEvent2Service,
                    statusDescriptionMap,
                    newMainBrownouts2Map,
                    newMainBrownoutsMap,
                    edosUtil, begin, end)).start();

        }
        //*************************子表数据计算*****************************************************************************/

        //******************************************************************************************************/


    }


}
