package com.gyee.generation.service;//package com.gyee.generation.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyee.common.contant.ContantXk;
import com.gyee.common.model.PointData;
import com.gyee.common.model.StringUtils;
import com.gyee.generation.init.CacheContext;
import com.gyee.generation.model.auto.ProBasicEquipment;
import com.gyee.generation.model.auto.ProBasicEquipmentPoint;
import com.gyee.generation.model.auto.ProEconEquipmentInfo15minute;
import com.gyee.generation.service.auto.IProEconEquipmentInfo15minuteService;
import com.gyee.generation.util.DateUtils;
import com.gyee.generation.util.realtimesource.IEdosUtil;
import com.gyee.generation.util.statisticcs.Initial;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class EquipmentInfo15minuteService {

    //    private static final Logger logger = LoggerFactory.getLogger(EquipmentInfo15minuteService.class);
    @Resource
    private IEdosUtil edosUtil;

    @Resource
    private IProEconEquipmentInfo15minuteService proEconEquipmentInfo15minuteService;


    /**
     * 计算设备15分钟信息
     */
    public void calEquipmentInfo15minute(Date recordDate) throws Exception {
        Calendar c = Calendar.getInstance();
        c.setTime(recordDate);

        int minute = c.get(Calendar.MINUTE);
        if (minute >= 0 && minute < 15) {
            c.set(Calendar.MINUTE, 0);
        } else if (minute >= 15 && minute < 30) {
            c.set(Calendar.MINUTE, 15);
        } else if (minute >= 30 && minute < 45) {
            c.set(Calendar.MINUTE, 30);
        } else if (minute >= 45) {
            c.set(Calendar.MINUTE, 45);
        }
        c.set(Calendar.SECOND, 0);
        Date end = c.getTime();
        c.add(Calendar.MINUTE, -15);
        Date begin = DateUtils.truncate(c.getTime());

        QueryWrapper<ProEconEquipmentInfo15minute> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("record_date", recordDate);

        //判断是否有重复记录，先删除重复记录
        List<String> idls = proEconEquipmentInfo15minuteService.list(queryWrapper)
                .stream()
                //                .filter(i -> i.getRecordDate().compareTo(recordDate)==0
                //                        && CacheContext.wtmap.containsKey(i.getWindturbineId())
                //           )
                .map(ProEconEquipmentInfo15minute::getId)
                .collect(Collectors.toList());

        if (idls.size() > 0) {

            proEconEquipmentInfo15minuteService.removeByIds(idls);

        }
        for (ProBasicEquipment wt : CacheContext.wtls) {
            if (CacheContext.wtpAimap.containsKey(wt.getId())) {
                Map<String, ProBasicEquipmentPoint> pointmap = CacheContext.wtpAimap.get(wt.getId());

                ProEconEquipmentInfo15minute pewp = new ProEconEquipmentInfo15minute();
                Initial.initial(pewp);
                pewp.setCompanyId(wt.getCompanyId());
                pewp.setWindpowerstationId(wt.getWindpowerstationId());
                pewp.setLineId(wt.getLineId());
                pewp.setProjectId(wt.getProjectId());
                pewp.setRegionId(wt.getRegionId());
                pewp.setRecordDate(recordDate);
                pewp.setWindturbineId(wt.getId());


                if (pointmap.containsKey(ContantXk.CJ_SSFS)) {
                    ProBasicEquipmentPoint point = pointmap.get(ContantXk.CJ_SSFS);
                    List<PointData> pointls = edosUtil.getHistoryDatasSnap(point.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000);
                    if (!pointls.isEmpty()) {
                        DoubleSummaryStatistics summaryStatistics = pointls.stream().mapToDouble(PointData::getPointValueInDouble).summaryStatistics();
                        //15分钟平均风速
                        pewp.setFpjfs(summaryStatistics.getAverage());
                    }

                }

                if (pointmap.containsKey(ContantXk.CJ_SSGL)) {
                    ProBasicEquipmentPoint point = pointmap.get(ContantXk.CJ_SSGL);
                    List<PointData> pointls = edosUtil.getHistoryDatasSnap(point.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000);
                    if (!pointls.isEmpty()) {
                        DoubleSummaryStatistics summaryStatistics = pointls.stream().mapToDouble(PointData::getPointValueInDouble).summaryStatistics();
                        //15分钟平均功率
                        pewp.setFpjgl(summaryStatistics.getAverage());
                    }
                }


                if (pointmap.containsKey(ContantXk.RFDL)) {
                    ProBasicEquipmentPoint point = pointmap.get(ContantXk.RFDL);

                    PointData beginValue = edosUtil.getHistMatrix(point.getNemCode(), begin.getTime() / 1000);
                    PointData endValue = edosUtil.getHistMatrix(point.getNemCode(), end.getTime() / 1000);
                    if (StringUtils.notEmp(beginValue) && StringUtils.notEmp(endValue)) {
                        //15分钟发电量
                        pewp.setFfdl(StringUtils.round(endValue.getPointValueInDouble() - beginValue.getPointValueInDouble(), 2));

                    }
                }

                calDetiall(pewp, end, begin, wt);
                calSimple(pewp, end, begin, wt);
                proEconEquipmentInfo15minuteService.save(pewp);

            }


        }

    }

    private void calDetiall(ProEconEquipmentInfo15minute pewp, Date end, Date begin, ProBasicEquipment wt) throws Exception {
        //        //                0	待机
        //                1	手动停机
        //                2	正常发电
        //                3	发电降出力
        //                4	故障
        //                5	故障受累
        //                6	检修
        //                7	检修受累
        //                8	限电降出力
        //                9	限电停机
        //                10	电网受累
        //                11	环境受累
        //                12	通讯中断
        //                13	设备离线

        double lastState = -1;//上一分钟状态

        double djsc = 0;//待机时长
        double sdtjsc = 0;//手动停机时长
        double zcfdsc = 0;//正常发电时长
        double fdjclsc = 0;//发电降出力时长
        double gzsc = 0;//故障时长
        double gzslsc = 0;//故障受累时长
        double jxsc = 0;//检修时长
        double jxslsc = 0;//检修受累时长
        double xdjclsc = 0;//限电降出力时长
        double xdtjsc = 0;//限电停机时长
        double dwslsc = 0;//电网受累时长
        double hjslsc = 0;//环境受累时长
        double txzdsc = 0;//通讯中断时长
        double sblxsc = 0;//设备离线时长

        Map<String, Map<String, ProBasicEquipmentPoint>> wtpAimap = CacheContext.wtpAimap;


        //上一分钟状态
        Map<String, ProBasicEquipmentPoint> aimap = wtpAimap.get(wt.getNemCode());
        if (wtpAimap.containsKey(ContantXk.MXZT)) {

            ProBasicEquipmentPoint point = aimap.get(ContantXk.MXZT);
            //按照分钟时间进行统计状态快照值
            List<PointData> pointls = edosUtil.getHistoryDatasSnap(point.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000);
            if (!pointls.isEmpty()) {
                for (PointData po : pointls) {

                    if (po.getPointValueInDouble() == 0) {

                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //待机时长加1分钟
                        djsc++;
                    } else if (po.getPointValueInDouble() == 1) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //手动停机时长加1分钟
                        sdtjsc++;
                    } else if (po.getPointValueInDouble() == 2) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //正常发电时长加1分钟
                        zcfdsc++;
                    } else if (po.getPointValueInDouble() == 3) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //发电降出力时长加1分钟
                        fdjclsc++;
                    } else if (po.getPointValueInDouble() == 4) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //故障时长加1分钟
                        gzsc++;
                    } else if (po.getPointValueInDouble() == 5) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //故障受累时长加1分钟
                        gzslsc++;
                    } else if (po.getPointValueInDouble() == 6) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //检修时长加1分钟
                        jxsc++;
                    } else if (po.getPointValueInDouble() == 7) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //检修受累时长加1分钟
                        jxslsc++;
                    } else if (po.getPointValueInDouble() == 8) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //限电降出力时长加1分钟
                        xdjclsc++;
                    } else if (po.getPointValueInDouble() == 9) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //限电停机时长加1分钟
                        xdtjsc++;
                    } else if (po.getPointValueInDouble() == 10) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //电网受累时长加1分钟
                        dwslsc++;
                    } else if (po.getPointValueInDouble() == 11) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //环境受累时长加1分钟
                        hjslsc++;
                    } else if (po.getPointValueInDouble() == 12) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //通讯中断时长加1分钟
                        txzdsc++;
                    } else if (po.getPointValueInDouble() == 13) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //设备离线时长加1分钟
                        sblxsc++;
                    }

                }

            }

        }

        //15分钟合计故障小时（明细）
        pewp.setFgzxsmx(new BigDecimal(gzsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计场内受累故障小时（明细）
        pewp.setFcnslgzxsmx(new BigDecimal(gzslsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计检修小时（明细）
        pewp.setFjxxsmx(new BigDecimal(jxsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计场内受累检修小时（明细）
        pewp.setFcnsljxxsmx(new BigDecimal(jxslsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计待机小时（明细）
        pewp.setFdjxsmx(new BigDecimal(djsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计缺陷降出力小时（明细）
        pewp.setFqxjclxsmx(new BigDecimal(fdjclsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计手动停机小时（明细）
        pewp.setFsdtjxsmx(new BigDecimal(sdtjsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计性能小时（明细）
        pewp.setFbwxsmx(new BigDecimal(zcfdsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计限电停机小时（明细）
        pewp.setFxdtjxsmx(new BigDecimal(xdtjsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计限电降出力小时（明细）
        pewp.setFxdjclxsmx(new BigDecimal(xdjclsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计场外受累电网小时（明细）
        pewp.setFcwsldwxsmx(new BigDecimal(dwslsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计场外受累电网小时（明细）
        pewp.setFcwsltqxsmx(new BigDecimal(hjslsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计通讯中断小时（明细）
        pewp.setFtxzdxsmx(new BigDecimal(txzdsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计离线小时（明细）
        pewp.setFlxxsmx(new BigDecimal(sblxsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());


        //*******************************************15分钟信息统计*********************************************************/


    }


    private void calSimple(ProEconEquipmentInfo15minute pewp, Date end, Date begin, ProBasicEquipment wt) throws Exception {
        //        0	待机
        //        1	运行
        //        2	故障
        //        3	检修
        //        4	限电
        //        5	受累
        //        6	离线
        //*******************************************15分钟信息统计*********************************************************/

        double lastState = -1;//上一分钟状态


        double djsc = 0;//待机时长
        double zcfdsc = 0;//正常发电时长
        double gzsc = 0;//故障时长
        double jxsc = 0;//检修时长
        double xdtjsc = 0;//限电停机时长
        double slsc = 0;//受累时长
        double txzdsc = 0;//通讯中断时长


        Map<String, Map<String, ProBasicEquipmentPoint>> wtpAimap = CacheContext.wtpAimap;


        Map<String, ProBasicEquipmentPoint> aimap = wtpAimap.get(wt.getNemCode());
        if (wtpAimap.containsKey(ContantXk.SBZT)) {

            ProBasicEquipmentPoint point = aimap.get(ContantXk.SBZT);
            //按照分钟时间进行统计状态快照值
            List<PointData> pointls = edosUtil.getHistoryDatasSnap(point.getNemCode(), begin.getTime() / 1000, end.getTime() / 1000);
            if (!pointls.isEmpty()) {
                for (PointData po : pointls) {

                    if (po.getPointValueInDouble() == 0) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //待机时长加1分钟
                        djsc++;
                    } else if (po.getPointValueInDouble() == 1) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //正常发电时长加1分钟
                        zcfdsc++;
                    } else if (po.getPointValueInDouble() == 2) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //故障时长加1分钟
                        gzsc++;
                    } else if (po.getPointValueInDouble() == 3) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //检修时长加1分钟
                        jxsc++;

                    } else if (po.getPointValueInDouble() == 4) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //限电停机时长加1分钟
                        xdtjsc++;
                    } else if (po.getPointValueInDouble() == 5) {
                        if (lastState != po.getPointValueInDouble()) {

                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }

                        //受累时长加1分钟
                        slsc++;

                    } else if (po.getPointValueInDouble() == 6) {
                        if (lastState != po.getPointValueInDouble()) {
                            //将当前状态保存到上一分钟状态
                            lastState = po.getPointValueInDouble();

                        }
                        //通讯中断时长加1分钟
                        txzdsc++;
                    }

                }

            }


        }


        //15分钟合计待机小时
        pewp.setFdjxs(new BigDecimal(gzsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计维护停机小时
        pewp.setFjxtjxs(new BigDecimal(jxsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        // 15分钟合计待机小时
        pewp.setFdjxs(new BigDecimal(djsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计运行小时
        pewp.setFyxxs(new BigDecimal(zcfdsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计限电小时
        pewp.setFxdxs(new BigDecimal(xdtjsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计通讯中断小时
        pewp.setFtxzdxs(new BigDecimal(txzdsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());
        //15分钟合计受累小时
        pewp.setFslxs(new BigDecimal(slsc).divide(new BigDecimal(60), 2, RoundingMode.HALF_EVEN).doubleValue());


        //*******************************************15分钟信息统计*********************************************************/
    }


}







