package com.gyee.runeconomy.service.analysis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gyee.common.model.PointData;
import com.gyee.common.model.StringUtils;
import com.gyee.common.util.CopyUtils;
import com.gyee.common.util.DateUtils;
import com.gyee.runeconomy.init.CacheContext;
import com.gyee.runeconomy.model.auto.*;
import com.gyee.runeconomy.service.auto.*;
import com.gyee.runeconomy.service.auto.impl.ProBasicMeterPointServiceImpl;
import com.gyee.runeconomy.service.auto.impl.ProEconAnalysisSubtableBottomServiceImpl;
import com.gyee.runeconomy.util.realtimesource.IEdosUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

//@Service
public class AnalysisNewService {

    @Resource
    private IEdosUtil edosUtil;

    @Resource
    private ProBasicMeterPointServiceImpl proBasicMeterPointService;

    @Resource
    private ProEconAnalysisSubtableBottomServiceImpl proEconAnalysisSubtableBottomService;

    @Resource
    private IProEconAnalysisSubtableBottomService ProEconAnalysisSubtableBottomService;
    @Resource
    private IProEconAnalysisSubprojectWindcannotService ProEconAnalysisSubprojectWindcannotService;
    @Resource
    private IProEconAnalysisSubprojectWindcanService ProEconAnalysisSubprojectWindcanService;

    @Resource
    private IProEconPowerstationInfoDay1Service proEconPowerstationInfoDay1Service;
    @Resource
    private IProEconPowerstationInfoDay3Service windpowerinfoday3Service;
    @Resource
    private IProEconShutdownEvent2Service shutdownevent2Service;

    @Resource
    private IProEconInOrOutSpeedTotalService inputoroutputspeedtotalService;

    @Resource
    private IProBasicProjectPlanService proBasicProjectPlanService;

    public void companys() throws Exception {


        // 获取当前日期
        Date currentDate = new Date();

        // 创建 Calendar 对象，并设置为当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);

        // 将时间设为0点
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        // 设置 beginDate 为前一天的0点
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date beginDate = calendar.getTime();
        // 初始化初始值
        Date initialFirstDayZeroHour = (Date) beginDate.clone();
        // 设置 endDate 为当天的0点
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date endDate = calendar.getTime();
        List<ProBasicMeterPoint> meterPoints = proBasicMeterPointService.getBaseMapper().selectList(null);
        List<ProEconAnalysisSubtableBottom> Listbat = new ArrayList<>();
        for (ProBasicPowerstation wp : CacheContext.wpls) {
            //            if (wp.getId().equals("SXJ_KGDL_XWT_FDC_STA")) continue;

            ////            补充数据可将其打开
            //            if (wp.getId().equals("SXJ_KGDL_FS_GDC_STA")) {
            //
            //                for (int g = 0; g <= 50; g++) {


            List<ProBasicMeterPoint> collect = meterPoints.stream().filter(i -> i.getWindpowerstationId().equals(wp.getId())).collect(Collectors.toList());
            for (ProBasicMeterPoint po : collect) {
                if (wp.getId().equals(po.getWindpowerstationId())) {

                    String point = po.getNemCode();
                    String name = po.getName();

                    //获取当前测点倍率
                    double magnification = po.getMagnification();

                    PointData begin = edosUtil.getSectionData(point, beginDate.getTime());
                    PointData end = edosUtil.getSectionData(point, endDate.getTime());

                    double temp1 = 0.0;
                    double temp2 = 0.0;

                    temp1 = begin.getPointValueInDouble();
                    temp2 = end.getPointValueInDouble();


                    ProEconAnalysisSubtableBottom vo = new ProEconAnalysisSubtableBottom();

                    vo.setId(StringUtils.getUUID());
                    vo.setRecordDate(beginDate);
                    vo.setWpid(wp.getId());
                    vo.setMeterId(begin.getPointName());
                    vo.setMeterName(name);
                    vo.setStopCode(temp2);
                    vo.setStopCodeModify(temp2);
                    vo.setDayValue((temp2 - temp1) * magnification);
                    vo.setDayValueModify((temp2 - temp1) * magnification);
                    Listbat.add(vo);
                }

            }
            //                    beginDate = DateUtils.addDays(beginDate, -1);
            //                    calendar.add(Calendar.DAY_OF_MONTH, -1);
            //                    endDate = calendar.getTime();
            //                }
            proEconAnalysisSubtableBottomService.batchAdd(Listbat);
            Listbat.clear();
            //             恢复初始值
            //            beginDate = initialFirstDayZeroHour;
            //            }


        }
    }


    public void saveWindProject(String beginDate, String endDate) throws Exception {
        //风场，
        Map<String, List<ProBasicMeterPoint>> wpmeterMap = CacheContext.wpmeterMap;
        Map<String, ProBasicMeterPoint> meterMap = CacheContext.meterMap;
        List<String> days = getDays(beginDate, endDate);
        for (String day : days) {
            Map<String, Object> bdzmap = new HashMap<>();
            bdzmap.put("record_date", DateUtils.parseDate(day));
            List<ProEconAnalysisSubtableBottom> currentDayBdz = ProEconAnalysisSubtableBottomService.listByMap(bdzmap);


            Map<String, Object> deleteparam = new HashMap<>();
            deleteparam.put("record_date", DateUtils.parseDate(day));
            ProEconAnalysisSubprojectWindcannotService.removeByMap(deleteparam);
            ProEconAnalysisSubprojectWindcanService.removeByMap(deleteparam);
            for (ProBasicProject project : CacheContext.pjls) {

                if (project.getWindpowerstationId().endsWith("GDC_STA")) {
                    continue;
                }
                List<ProEconAnalysisSubtableBottom> currentDay = currentDayBdz.stream().filter(i -> i.getWpid().equals(project.getWindpowerstationId())).collect(Collectors.toList());
                if (StringUtils.isEmpty(currentDay)) {
                    continue;
                }
                //算出工程发电量
                List<String> fdls = wpmeterMap.get(project.getWindpowerstationId()).stream()
                        .filter(i -> (
                                i.getProjectId().equals(project.getId()) && i.getMeterSort().equals("主") && i.getMeterType().equals("进线") && i.getUniformCode().equals("ZXYG")
                        )).map(i -> i.getNemCode()).collect(Collectors.toList());

                double generatingcapacity = 0;
                for (String meterid : fdls) {
                    generatingcapacity += currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().isPresent() ? currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().get().getDayValueModify().doubleValue() : 0.0;
                }

                //总发电量
                List<String> zfdls = wpmeterMap.get(project.getWindpowerstationId()).stream()
                        .filter(i -> (
                                i.getMeterSort().contains("主") && i.getMeterType().contains("进线") && i.getUniformCode().contains("ZXYG")
                        )).map(i -> i.getNemCode()).collect(Collectors.toList());

                double zfdl = 0;
                for (String meterid : zfdls) {
                    zfdl += currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().isPresent() ? currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().get().getDayValueModify().doubleValue() : 0.0;
                }
                //算上网电量和购网电量
                double swdl = 0;
                double gwdl = 0;
                double fcfdl = 0;
                List<ProBasicMeterPoint> fcswmeter = wpmeterMap.get(project.getWindpowerstationId()).stream()
                        .filter(i -> (
                                i.getMeterSort().equals("主") && i.getMeterType().equals("出线") && i.getUniformCode().equals("ZXYG") && i.getProjectId().contains(project.getId())
                        )).collect(Collectors.toList());
                List<ProBasicMeterPoint> fcgwmeter = wpmeterMap.get(project.getWindpowerstationId()).stream()
                        .filter(i -> (
                                i.getMeterSort().equals("主") && i.getMeterType().equals("出线") && i.getUniformCode().equals("FXYG") && i.getProjectId().contains(project.getId())
                        )).collect(Collectors.toList());
                if (fcswmeter != null && fcswmeter.size() > 1) {
                    String[] lineids = fcswmeter.get(0).getLineId().split("\\|");

                    fcfdl = Arrays.stream(lineids).map(lineid ->
                                    wpmeterMap.get(project.getWindpowerstationId())
                                            .stream().filter(j -> j.getMeterSort().equals("主") && j.getMeterType().equals("进线") && j.getUniformCode().equals("ZXYG") && j.getLineId().equals(lineid)).findFirst().get())
                            .mapToDouble(linemeterpoint2 -> currentDay.stream()
                                    .filter(currentBdz -> currentBdz.getMeterId().equals(linemeterpoint2.getNemCode()))
                                    .findFirst().get().getDayValueModify()).sum();


                }
                //算出
                Double dayvaluesw = currentDay.stream().filter(currentBdz -> fcswmeter.contains(meterMap.get(currentBdz.getMeterId()))).mapToDouble(ProEconAnalysisSubtableBottom::getDayValueModify).sum();
                Double dayvaluegw = currentDay.stream().filter(currentBdz -> fcgwmeter.contains(meterMap.get(currentBdz.getMeterId()))).mapToDouble(ProEconAnalysisSubtableBottom::getDayValueModify).sum();
                swdl = fcfdl != 0 ? generatingcapacity / fcfdl * dayvaluesw : 0;
                gwdl = fcfdl != 0 ? generatingcapacity / fcfdl * dayvaluegw : 0;

                double fczyb = 0;
                List<String> fczybmeterids = wpmeterMap.get(project.getWindpowerstationId()).stream()
                        .filter(i -> (
                                i.getMeterSort().equals("主") && i.getMeterType().equals("站用变") && i.getUniformCode().equals("ZXYG")
                        )).map(i -> i.getNemCode()).collect(Collectors.toList());
                for (String meterid : fczybmeterids) {
                    fczyb += currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().isPresent() ? currentDay.stream().filter(i -> i.getMeterId().equals(meterid)).findFirst().get().getDayValueModify().doubleValue() : 0.0;
                }


                ProEconAnalysisSubprojectWindcan can = new ProEconAnalysisSubprojectWindcan();
                ProEconAnalysisSubprojectWindcannot cannot = new ProEconAnalysisSubprojectWindcannot();
                //                ProEconAnalysisMain mainValues = getMainValues(day, project.getWindpowerstationId());
                //                can.setTid(mainValues.getId());
                can.setProjectId(project.getId());
                can.setWpid(project.getWindpowerstationId());
                can.setRecordDate(DateUtils.parseDate(day));
                can.setZjrl(project.getCapacity() / 10);


                //                can.setFdl(generatingcapacity / 10000);
                can.setFdl(generatingcapacity);
                if (project.getId().equals("SBQ04_GC")) {
                    //                    List<Analysissubstationpv> analysissubstationpvs = analysissubstationpvService.listByMap(bdzmap);
                    //                    Double hzj_swdl = analysissubstationpvs.stream().filter(i -> i.getWpid().equals("HZJ_GDC")).findFirst().get().getFdl();
                    //                    Double wgejx = currentDayBdz.stream().filter(i -> i.getMeterId().equals(WGEJX)).findFirst().get().getDayValueModify();
                    //                    can.setSwdl((swdl-wgejx)/10000-hzj_swdl);
                } else {
                    can.setSwdl(swdl);
                    //                    can.setSwdl(swdl / 10000);
                }
                //                can.setGwdl(gwdl/ 10000);
                can.setGwdl(gwdl);
                //                can.setCydl(fcfdl != 0.0 ? (generatingcapacity / zfdl * fczyb) / 10000 : 0.0);
                can.setCydl(fcfdl != 0.0 ? (generatingcapacity / zfdl * fczyb) : 0.0);

                QueryWrapper<ProEconPowerstationInfoDay1> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("record_date", DateUtils.parseDate(day));
                queryWrapper.eq("foreign_key_id", project.getId());
                ProEconPowerstationInfoDay1 w = proEconPowerstationInfoDay1Service.getOne(queryWrapper);
                QueryWrapper<ProEconPowerstationInfoDay3> wWrapper = new QueryWrapper<>();
                wWrapper.eq("record_date", DateUtils.parseDate(day));
                wWrapper.eq("foreign_key_id", project.getId());
                ProEconPowerstationInfoDay3 one = windpowerinfoday3Service.getOne(wWrapper);
                QueryWrapper<ProEconShutdownEvent2> shutparams = new QueryWrapper<>();
                shutparams.eq("stop_time", DateUtils.parseDate(day));
                shutparams.eq("project_id", project.getId());
                //shutparams.put("statuscode",4);
                List<ProEconShutdownEvent2> shut = shutdownevent2Service.list(shutparams);

                Map<String, Object> inputparam = new HashMap<>();
                inputparam.put("record_date", DateUtils.parseDate(day));
                inputparam.put("project_id", project.getId());
                List<ProEconInOrOutSpeedTotal> inputoroutputspeedtotals = inputoroutputspeedtotalService.listByMap(inputparam);
                if (StringUtils.isNotEmpty(inputoroutputspeedtotals)) {
                    OptionalDouble average = inputoroutputspeedtotals.stream().filter(i -> i.getDayInputSmall() != null).mapToDouble(ProEconInOrOutSpeedTotal::getDayInputSmall).average();
                    if (average.isPresent()) {
                        can.setPjqrfs(average.getAsDouble());
                    } else {
                        can.setPjqrfs(0.0);
                    }
                } else {
                    can.setPjqrfs(0.0);
                }
                if (StringUtils.isNotNull(w)) {
                    //性能不好降风速
                    Double speed = w.getRpjfs().doubleValue();
                    if (speed < 5) {
                        can.setQpjfx(speed);
                    } else if (speed < 6) {
                        can.setQpjfx(speed - 0.2);
                    } else if (speed < 7) {
                        can.setQpjfx(speed - 0.3);
                    } else if (speed < 8) {
                        can.setQpjfx(speed - 0.4);
                    } else if (speed < 9) {
                        can.setQpjfx(speed - 0.5);
                    } else if (speed < 10) {
                        can.setQpjfx(speed - 0.6);
                    } else {
                        can.setQpjfx(speed - 0.8);
                    }
                    //                    can.setQpjfx(w.getSpeed());
                    //                    can.setFjgzsj(w.getFaultTime());
                    //                    can.setFjjxsj(w.getMaintainTime());
                    //                    can.setZdcl(w.getMaxPower());
                    //                    can.setZxcl(w.getMinPower());
                } else {

                    can.setQpjfx(0.0);
                    can.setFjgzsj(0.0);
                    can.setFjjxsj(0.0);
                    can.setZdcl(0.0);
                    can.setZxcl(0.0);
                }

                if (StringUtils.isNotNull(one)) {
                    //                    can.setFjgzdl(one.getDaynhgzssdl() / 10000);
                    //                    can.setXddl(one.getDaynhxdssdl() / 10000);
                    //                    can.setXnssdl(one.getDaynhqfdl() / 10000);
                    //                    can.setFjjxdl(one.getDaynhwhssdl() / 10000);
                } else {
                    can.setFjgzdl(0.0);
                    can.setXddl(0.0);
                    can.setXnssdl(0.0);
                    can.setFjjxdl(0.0);
                }
                if (StringUtils.isNotEmpty(shut)) {
                    can.setGzcs(Double.valueOf(shut.stream().filter(i -> i.getStatusCode() == 2).collect(Collectors.toList()).size()));
                } else {
                    can.setGzcs(0.0);
                }
                can.setFdlscada(can.getFdl() * 1.005);
                can.setZhcydl(can.getFdl() + can.getGwdl() - can.getSwdl());
                can.setZhcydll(can.getFdl() != 0 ? can.getZhcydl() / can.getFdl() * 100 : 0.0);
                can.setZhcydlscada(can.getFdlscada() + can.getGwdl() - can.getSwdl());
                can.setZhcydllscada(can.getFdlscada() != 0 ? can.getZhcydlscada() / can.getFdlscada() * 100 : 0.0);
                can.setCydll(can.getFdl() != 0 ? can.getCydl() / can.getFdl() : 0.0);
                can.setLyxs(can.getFdl() / can.getZjrl());
                can.setLyxsscada(can.getFdlscada() / can.getZjrl());
                if (can != null) {
                    Double xddl = can.getXddl();
                    Double fdl = can.getFdl();
                    if (xddl != null && fdl != null) {
                        can.setQfl(xddl + fdl != 0 ? xddl / (xddl + fdl) * 100 : 0.0);
                    } else {
                        can.setQfl(0.0);
                    }
                }

                if (can.getFdl() != null && can.getFjgzdl() != null && can.getFjjxdl() != null && can.getXddl() != null) {
                    can.setLlfdl(can.getFdl() + can.getFjgzdl() + can.getFjjxdl() + can.getXddl());  //+can.getXnssdl()
                } else {
                    can.setLlfdl(0.0);
                }

                if (can.getFdlscada() != null && can.getFjgzdl() != null && can.getFjjxdl() != null && can.getXddl() != null) {
                    can.setLlfdlscada(can.getFdlscada() + can.getFjgzdl() + can.getFjjxdl() + can.getXddl());//+can.getXnssdl()
                } else {
                    can.setLlfdl(0.0);
                }

                can.setYjhfdl(getYjhfdl(project.getId(), day));
                can.setDnaqts(getDnljts(day));
                can.setCnsldwdl(0.0);
                can.setCnsldwsj(0.0);
                can.setCnsljxdl(0.0);
                can.setCnsljxsj(0.0);
                can.setCwsldwdl(0.0);
                can.setCwsldwsj(0.0);
                can.setCwsljxdl(0.0);
                can.setCwsljxsj(0.0);
                can.setZrzhdl(0.0);
                can.setZrzhsj(0.0);
                can.setXdsj(0.0);
                can.setSyzgzdl(0.0);
                can.setSyzgzsj(0.0);
                can.setJdxlgzdl(0.0);
                can.setJdxlgzsj(0.0);
                can.setSyzjxdl(0.0);
                can.setSyzjxsj(0.0);
                can.setJdxljx(0.0);
                can.setJdxljxsj(0.0);
                can.setLjaqts(0.0);
                can.setQw(0.0);
                can.setTq("");
                can.setFx("");
                can.setEdpjfs(0.0);
                can.setYpjkqmd(0.0);

                CopyUtils.copy(can, cannot);
                ProEconAnalysisSubprojectWindcanService.save(can);
                ProEconAnalysisSubprojectWindcannotService.save(cannot);
            }
        }
    }

    private List<String> getDays(String beginDate, String endDate) {
        List<String> days = null;
        if (StringUtils.isNotEmpty(beginDate) && StringUtils.isNotEmpty(endDate)) {
            days = DateUtils.getDays(beginDate, endDate);
        } else {
            days = new ArrayList<>();
            days.add(DateUtils.getYesterdayStr("yyyy-MM-dd"));
        }
        return days;
    }

    private double getYjhfdl(String id, String day) {
        String[] ny = new String[2];
        Date date = DateUtils.parseDate(day);
        ny[0] = String.format("%tY", date);
        ny[1] = String.format("%tm", date);
        QueryWrapper<ProBasicProjectPlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", id);
        queryWrapper.eq("year", ny[0]);
        queryWrapper.eq("month", ny[1]);
        ProBasicProjectPlan one = proBasicProjectPlanService.getOne(queryWrapper);
        if (StringUtils.isNotNull(one)) {
            return (one.getGeneratingCapacity());
        }
        return 0.0;

    }

    private Double getDnljts(String day) {
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtils.parseDate(day));
        return Double.valueOf(c.get(Calendar.DAY_OF_YEAR));
    }

}
