package com.gyee.runeconomy.service.Electricity;

import com.gyee.common.contant.ContantXk;
import com.gyee.common.util.DateUtils;
import com.gyee.common.util.SortUtils;
import com.gyee.runeconomy.dto.CoulometricVo;
import com.gyee.runeconomy.dto.ElectricityVo;
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.ProEconStationPowerServiceImpl;
import com.gyee.runeconomy.util.MathUtil;
import com.gyee.runeconomy.util.StringUtils;
import com.gyee.runeconomy.util.realtimesource.IEdosUtil;
import org.springframework.stereotype.Service;

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

@Service
public class Electricityservice {

    @Resource
    private IProBasicPowerstationPointService proBasicPowerstationPointService;
    @Resource
    private IProEconTargetdataService proEconTargetdataService;
    @Resource
    private IProEconTargetdataFristService proEconTargetdataFristService;

    @Resource
    private IProEconPowerstationInfoDay1Service proEconPowerstationInfoDay1Service;

    @Resource
    private IProEconPowerstationInfoDay5Service proEconPowerstationInfoDay5Service;

    @Resource
    private ProEconStationPowerServiceImpl powerService;

    @Resource
    private IEdosUtil edosUtil;

    @Resource
    private IProBasicProjectPlanService proBasicProjectPlanService;

    @Resource
    private IProBasicFeasibilityStudyService proBasicFeasibilityStudyService;
    private final String QS = "0";
    private final String FD = "-1";
    private final String GF = "-2";

    public Map<String, Object> planvalue(String wpId, String timetype, String year) throws Exception {

        List<ElectricityVo> vos = new ArrayList<ElectricityVo>();
        Map<String, Object> map = new LinkedHashMap<>();
        if (wpId.endsWith(QS) || wpId.endsWith(FD) || wpId.endsWith(GF) || CacheContext.wpmapls.containsKey(wpId)) {

            List<ProBasicPowerstation> wplist = new ArrayList<>();
            if (CacheContext.wpmapls.containsKey(wpId)) {
                wplist = CacheContext.wpmapls.get(wpId);
            }
            //            HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
            //            List<ProBasicPowerstation> wplsToken = tokenService.getWpls(request);
            for (ProBasicPowerstation wp : CacheContext.wpls) {
                if (wpId.contains(FD)) {
                    if (wp.getId().endsWith("FDC_STA")) {
                        wplist.add(wp);
                    }
                } else if (wpId.contains(GF)) {
                    if (wp.getId().endsWith("GDC_STA")) {
                        wplist.add(wp);
                    }
                } else if (wpId.contains(QS)) {
                    wplist.add(wp);
                }
            }


            if (timetype.contains("month")) {

                if (!wplist.isEmpty()) {
                    int day = 0;

                    //                    // 当前年份
                    Calendar cal = Calendar.getInstance();
                    int dqnf = cal.get(Calendar.YEAR);
                    int currentyear = Integer.parseInt(year);

                    // 当月第一天0点值
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date());
                    // 设置年份为传递的currentyear
                    calendar.set(Calendar.YEAR, currentyear);
                    calendar.set(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 yearHour = calendar.getTime();

                    // 获取当前日期
                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(new Date());
                    calendar2.set(Calendar.YEAR, currentyear); // 根据当前年份变化
                    // 设置为本年一月一号0点
                    calendar2.set(Calendar.MONTH, Calendar.JANUARY); // 0表示一月
                    calendar2.set(Calendar.DAY_OF_MONTH, 1);
                    calendar2.set(Calendar.HOUR_OF_DAY, 0);
                    calendar2.set(Calendar.MINUTE, 0);
                    calendar2.set(Calendar.SECOND, 0);
                    calendar2.set(Calendar.MILLISECOND, 0);

                    Date firstDayZeroHour = calendar2.getTime();

                    // 获取firstDayZeroHour的月份
                    Calendar calFirstDayZeroHour = Calendar.getInstance();
                    calFirstDayZeroHour.setTime(firstDayZeroHour);
                    int calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;
                    //当前时间月份
                    Calendar calendar7 = Calendar.getInstance();
                    int currentMonth = calendar7.get(Calendar.MONTH);
                    currentMonth = currentMonth + 1;

                    for (int i = 1; i <= 12; i++) {
                        double bnjhdlsum = 0.0;
                        double yeardlsum = 0.0;
                        double bysjdlhjsum = 0.0;
                        double rfdlsj = 0.0;
                        BigDecimal dqzqlsum = null;
                        BigDecimal rfdlyclsum = null;
                        day = i;
                        for (ProBasicPowerstation wpls : wplist) {

                            //计划电量
                            List<ProBasicProjectPlan> currentls = proBasicProjectPlanService.getmonthList1(String.valueOf(day), currentyear); //本月所有集合

                            List<ProBasicProjectPlan> yearls = proBasicProjectPlanService.getList(String.valueOf(currentyear));
                            List<ProBasicProjectPlan> yearjh = yearls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpls.getId())).collect(Collectors.toList());

                            yeardlsum += yearjh.stream().mapToDouble(ProBasicProjectPlan::getGeneratingCapacity).sum(); //本年计划电量合


                            //计划电量本年所有集合
                            List<ProBasicProjectPlan> currentjh = currentls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpls.getId())).collect(Collectors.toList());
                            bnjhdlsum += currentjh.stream().mapToDouble(ProBasicProjectPlan::getGeneratingCapacity).sum(); //本月计划电量合

                            ProBasicPowerstationPoint rfdlvalue = proBasicPowerstationPointService.getPowerstationPoint(wpls.getId(), ContantXk.RFDL);
                            rfdlsj = edosUtil.getRealData(rfdlvalue).getPointValueInDouble();

                            //实际电量
                            List<ProEconPowerstationInfoDay5> sjdlls = proEconPowerstationInfoDay5Service.getmax(wpls.getId(), firstDayZeroHour);
                            if (!sjdlls.isEmpty() && sjdlls != null) {
                                bysjdlhjsum += sjdlls.get(0).getYfdldb().doubleValue();
                            }

                            //短期预测准确率和日发电量预测
                            List<ProEconStationPower> dqycls = powerService.getlist(wpls.getId(), firstDayZeroHour);

                            if (!dqycls.isEmpty() && dqycls != null) {
                                //                                dqzqlsum = dqycls.stream().map(ProEconStationPower::getPowerAccuracy).reduce(BigDecimal.ZERO, BigDecimal::add);
                                double average = dqycls.stream()
                                        .mapToDouble(power -> power.getPowerAccuracy().doubleValue())
                                        .average()
                                        .orElse(0.0);

                                dqzqlsum = BigDecimal.valueOf(StringUtils.round(average, 2));
                                rfdlyclsum = dqycls.stream().map(ProEconStationPower::getDayPowerForecast).reduce(BigDecimal.ZERO, BigDecimal::add);
                            }
                        }


                        ElectricityVo vo = new ElectricityVo();

                        //添加计划电量
                        vo.setJhdl(StringUtils.round(bnjhdlsum, 2));
                        vo.setHours(i);

                        // 获取当前月份的最后一天的最大时间
                        //                        Calendar calendar = Calendar.getInstance();
                        //                        calendar.setTime(date1);
                        //                        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                        //                        calendar.set(Calendar.HOUR_OF_DAY, 23);
                        //                        calendar.set(Calendar.MINUTE, 59);
                        //                        calendar.set(Calendar.SECOND, 59);
                        //                        Date endOfDayOfLastDayOfMonth = calendar.getTime();
                        //
                        //                        //添加实际电量
                        //                        PointData data = edosUtil.getSectionData(month, endOfDayOfLastDayOfMonth.getTime());
                        //                        PointData data = edosUtil.getSectionData(month, date1.getTime());
                        if (calFirstMonth == currentMonth && currentyear == dqnf) {
                            //                            vo.setSjdl(StringUtils.round((bysjdlhjsum / 10000) + (rfdlsj /10000), 2));
                            vo.setSjdl(StringUtils.round(bysjdlhjsum / 10000, 2));
                        } else {
                            vo.setSjdl(StringUtils.round(bysjdlhjsum / 10000, 2));
                        }


                        //添加当月占比
                        if (bnjhdlsum != 0) {
                            vo.setDyzb(StringUtils.round(((bysjdlhjsum / 10000) / bnjhdlsum) * 100, 0));
                        } else {
                            vo.setDyzb(0.0);
                        }

                        //添加全年占比
                        if (yeardlsum != 0) {
                            vo.setQnzb(StringUtils.round(((bysjdlhjsum / 10000) / yeardlsum) * 100, 0));
                        } else {
                            vo.setQnzb(0.0);
                        }
                        //添加超短期准确率
                        vo.setDqzql(dqzqlsum);

                        //添加日发电量预测
                        if (rfdlyclsum != null) {
                            vo.setRfdlyc(rfdlyclsum.divide(BigDecimal.valueOf(10000), 2));
                        } else {
                            vo.setRfdlyc(BigDecimal.valueOf(0.0));
                        }

                        firstDayZeroHour = DateUtils.addMonths(firstDayZeroHour, +1);

                        calFirstDayZeroHour.setTime(firstDayZeroHour);
                        calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;

                        vos.add(vo);
                        SortUtils.sort(vos, "hours", SortUtils.ASC);
                        map.put("value", vos);
                    }

                    double yeardlsum = 0.0;
                    double bnsjdlhjsum = 0.0;
                    double rfdlsjhj = 0.0;
                    BigDecimal dqzqlhjsum = null;
                    BigDecimal rfdlychjsum = null;

                    //计算合计
                    for (ProBasicPowerstation wpls : wplist) {
                        //计划电量合计
                        List<ProBasicProjectPlan> yearls = proBasicProjectPlanService.getList(String.valueOf(currentyear));
                        List<ProBasicProjectPlan> yearjh = yearls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpls.getId())).collect(Collectors.toList());

                        yeardlsum += yearjh.stream().mapToDouble(ProBasicProjectPlan::getGeneratingCapacity).sum(); //本年计划电量合

                        //实际电量合计
                        //                        PointData bnsjdlhj = edosUtil.getHistMatrix(nfdl, currentDate.getTime() / 1000);
                        //                        bnsjdlhjsum += bnsjdlhj.getPointValueInDouble();

                        ProBasicPowerstationPoint rfdlvalue = proBasicPowerstationPointService.getPowerstationPoint(wpls.getId(), ContantXk.RFDL);
                        rfdlsjhj = edosUtil.getRealData(rfdlvalue).getPointValueInDouble();


                        List<ProEconPowerstationInfoDay5> sjdlls = proEconPowerstationInfoDay5Service.getmax(wpls.getId(), yearHour);
                        if (!sjdlls.isEmpty() && sjdlls != null) {
                            bnsjdlhjsum += sjdlls.get(0).getNfdldb().doubleValue();
                        }

                        Calendar calendar1 = Calendar.getInstance();
                        calendar1.set(Calendar.YEAR, currentyear);  // 设置年份为当前传入的年份
                        calendar1.set(Calendar.DAY_OF_YEAR, 1);
                        calendar1.set(Calendar.HOUR_OF_DAY, 0);
                        calendar1.set(Calendar.MINUTE, 0);
                        calendar1.set(Calendar.SECOND, 0);
                        calendar1.set(Calendar.MILLISECOND, 0);

                        Date firstDayOfYearZeroHour = calendar1.getTime();

                        List<ProEconStationPower> dqyc = powerService.getlist2(wpls.getId(), firstDayOfYearZeroHour, currentyear);
                        if (!dqyc.isEmpty() && dqyc != null) {
                            //                            dqzqlhjsum = dqyc.stream().map(ProEconStationPower::getPowerAccuracy).reduce(BigDecimal.ZERO, BigDecimal::add);
                            rfdlychjsum = dqyc.stream().map(ProEconStationPower::getDayPowerForecast).reduce(BigDecimal.ZERO, BigDecimal::add);

                            double average = dqyc.stream()
                                    .mapToDouble(power -> power.getPowerAccuracy().doubleValue())
                                    .average()
                                    .orElse(0.0);

                            dqzqlhjsum = BigDecimal.valueOf(StringUtils.round(average, 2));
                        }
                        map.put("bnjhdlhj", MathUtil.twoBit(yeardlsum));
                        if (null == rfdlychjsum) {
                            rfdlychjsum=BigDecimal.ZERO;
                        }
                        map.put("rfdlychj", rfdlychjsum.divide(BigDecimal.valueOf(10000), 2));
                        //                        map.put("bnsjdlhj", MathUtil.twoBit((bnsjdlhjsum / 10000) + (rfdlsjhj / 10000)));
                        map.put("bnsjdlhj", MathUtil.twoBit(bnsjdlhjsum / 10000));
                        if (yeardlsum != 0) {
                            map.put("qnzbhj", StringUtils.round(((bnsjdlhjsum / 10000) / yeardlsum) * 100, 0));
                        } else {
                            map.put("qnzbhj", 0.0);
                        }
                        map.put("dqzqlhj", dqzqlhjsum);

                    }

                }
            }


        }
        return map;

    }

    public Map<String, Object> coulometric(String wpId, String year) throws Exception {

        List<ProBasicPowerstation> wplsG = CacheContext.wplsG.stream().filter(g -> wpId.equals(g.getId())).collect(Collectors.toList());
        List<CoulometricVo> vos = new ArrayList<CoulometricVo>();
        Map<String, Object> map = new LinkedHashMap<>();

        int day = 0;
        int ts = 1;
        //当前年份
        Calendar cal = Calendar.getInstance();
        int dqnf = cal.get(Calendar.YEAR);//本年
        int currentyear = Integer.parseInt(year);//本年


        //当月第一天0点值
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        // 设置年份为传递的currentyear
        calendar.set(Calendar.YEAR, currentyear);
        calendar.set(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 yearHour = calendar.getTime();

        // 获取当前日期
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(new Date());
        calendar2.set(Calendar.YEAR, currentyear); // 根据当前年份变化
        // 设置为本年一月一号0点
        calendar2.set(Calendar.MONTH, Calendar.JANUARY); // 0表示一月
        calendar2.set(Calendar.DAY_OF_MONTH, 1);
        calendar2.set(Calendar.HOUR_OF_DAY, 0);
        calendar2.set(Calendar.MINUTE, 0);
        calendar2.set(Calendar.SECOND, 0);
        calendar2.set(Calendar.MILLISECOND, 0);
        Date firstDayZeroHour = calendar2.getTime();


        // 获取firstDayZeroHour的月份
        Calendar calFirstDayZeroHour = Calendar.getInstance();
        calFirstDayZeroHour.setTime(firstDayZeroHour);
        int calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;

        //当前时间月份
        int currentMonth = calendar.get(Calendar.MONTH) + 1;


        // 将calendar2的时间设置回当前日期
        calendar2.setTime(new Date());

        //年电量
        double yeardlsum = 0.0;
        double kyyeardlsum = 0.0;

        double bnsjdlhjsum = 0.0;

        double rfdlsjhj = 0.0;

        double bnrzqdhjsum = 0.0;

        double dxxsssum = 0.0;


        for (int i = 1; i <= 12; i++) {

            //本月计划电量
            double byjhdlsum = 0.0;
            //本月实际电量合计
            double bysjdlhjsum = 0.0;
            double dxxss = 0.0;
            //本月日照强度合计
            double byrzqdhjsum = 0.0;
            //本月可研电量合计
            double bykydlhjsum = 0.0;

            double rfdlsj = 0.0;

            if (calFirstMonth == currentMonth && dqnf == currentyear) {
                Calendar calendar5 = Calendar.getInstance();
                ts = calendar5.get(Calendar.DAY_OF_MONTH);
            } else {
                // 获取当前月份的天数
                ts = calFirstDayZeroHour.getActualMaximum(Calendar.DAY_OF_MONTH);
            }

            day = i;
            for (ProBasicPowerstation wpls : wplsG) {

                //计划电量-循环所有场站当前月集合
                List<ProBasicProjectPlan> currentls = proBasicProjectPlanService.getmonthList1(String.valueOf(day), currentyear);

                //当前场站循环当前月
                List<ProBasicProjectPlan> currentjh = currentls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpls.getId())).collect(Collectors.toList());
                byjhdlsum = currentjh.stream().mapToDouble(ProBasicProjectPlan::getGeneratingCapacity).sum(); //本月计划电量合

                //可研电量-循环所有场站当前月集合
                List<ProBasicFeasibilityStudy> currentkyls = proBasicFeasibilityStudyService.getmonthList1(String.valueOf(day), currentyear);

                //当前场站循环当前月
                List<ProBasicFeasibilityStudy> currentky = currentkyls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpls.getId())).collect(Collectors.toList());
                bykydlhjsum = currentky.stream().mapToDouble(ProBasicFeasibilityStudy::getGeneratingCapacity).sum(); //本月可研电量合

                ProBasicPowerstationPoint rfdlvalue = proBasicPowerstationPointService.getPowerstationPoint(wpls.getId(), ContantXk.RFDL);
                rfdlsj = edosUtil.getRealData(rfdlvalue).getPointValueInDouble();
                //当前场站循环月实际电量
                List<ProEconPowerstationInfoDay5> sjdlls = proEconPowerstationInfoDay5Service.getmax(wpls.getId(), firstDayZeroHour);
                if (!sjdlls.isEmpty() && sjdlls != null) {
                    bysjdlhjsum = sjdlls.get(0).getYfdldb().doubleValue();
                }

                //当前场站循环月日照强度
                List<ProEconPowerstationInfoDay1> rzqdls = proEconPowerstationInfoDay1Service.getmax(wpls.getId(), firstDayZeroHour);
                if (!rzqdls.isEmpty() && rzqdls != null) {
                    byrzqdhjsum = rzqdls.get(0).getYpjfs().doubleValue();
                }
                //等效发电小时数算法
                //                dxxss = (bysjdlhjsum) / (wpls.getJrCapacity() * ts * 8) * ts * 24;
                dxxss = (bysjdlhjsum) / wpls.getJrCapacity();
                dxxsssum += StringUtils.round(dxxss, 0);
            }


            CoulometricVo vo = new CoulometricVo();

            //添加计划电量
            vo.setJhdl(StringUtils.round(byjhdlsum, 2));
            vo.setHours(i);
            //添加实际电量
            if (calFirstMonth == currentMonth && dqnf == currentyear) {
                //                vo.setSjdl(StringUtils.round((bysjdlhjsum / 10000) + (rfdlsj / 10000), 2));
                vo.setSjdl(StringUtils.round(bysjdlhjsum / 10000, 2));
            } else {
                vo.setSjdl(StringUtils.round(bysjdlhjsum / 10000, 2));
            }
            vo.setKydl(StringUtils.round(bykydlhjsum, 2));
            //添加完成情况
            if (byjhdlsum != 0) {
                vo.setWcqk(StringUtils.round(((bysjdlhjsum / 10000) / byjhdlsum) * 100, 0));
            } else {
                vo.setWcqk(0.0);
            }
            //添加完成情况
            if (bykydlhjsum != 0) {
                vo.setKywcqk(StringUtils.round(((bysjdlhjsum / 10000) / bykydlhjsum) * 100, 0));
            } else {
                vo.setKywcqk(0.0);
            }
            //等效小时数
            vo.setDxfdxs(StringUtils.round(dxxss, 0));

            //添加日照强度
            vo.setRzqd(byrzqdhjsum);

            //            firstDayZeroHour = DateUtils.addMonths(firstDayZeroHour, +1);
            vos.add(vo);
            SortUtils.sort(vos, "hours", SortUtils.ASC);
            map.put("value", vos);

            // 月份增加一个月
            firstDayZeroHour = DateUtils.addMonths(firstDayZeroHour, 1);
            calFirstDayZeroHour.setTime(firstDayZeroHour);
            calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;
            ts = calFirstDayZeroHour.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        List<ProBasicProjectPlan> yearls = proBasicProjectPlanService.getList(String.valueOf(currentyear));
        List<ProBasicProjectPlan> yearjh = yearls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpId)).collect(Collectors.toList());

        List<ProBasicFeasibilityStudy> kyyearls = proBasicFeasibilityStudyService.getList(String.valueOf(currentyear));
        List<ProBasicFeasibilityStudy> kyyearjh = kyyearls.stream().filter(wp -> wp.getWindpowerstationId().equals(wpId)).collect(Collectors.toList());

        yeardlsum = yearjh.stream().mapToDouble(ProBasicProjectPlan::getGeneratingCapacity).sum();
        kyyeardlsum = kyyearjh.stream().mapToDouble(ProBasicFeasibilityStudy::getGeneratingCapacity).sum();

        ProBasicPowerstationPoint rfdlvalue = proBasicPowerstationPointService.getPowerstationPoint(wpId, ContantXk.RFDL);
        rfdlsjhj = edosUtil.getRealData(rfdlvalue).getPointValueInDouble();

        List<ProEconPowerstationInfoDay5> sjdlls = proEconPowerstationInfoDay5Service.getmax(wpId, yearHour);
        if (!sjdlls.isEmpty() && sjdlls != null) {
            bnsjdlhjsum += sjdlls.get(0).getNfdldb().doubleValue();
        }

        List<ProEconPowerstationInfoDay1> rzqddlls = proEconPowerstationInfoDay1Service.getmax(wpId, yearHour);
        if (!rzqddlls.isEmpty() && rzqddlls != null) {
            bnrzqdhjsum += rzqddlls.get(0).getNpjfs().doubleValue();
        }

        map.put("jhdlhj", StringUtils.round(yeardlsum, 2));
        map.put("kydlhj", StringUtils.round(kyyeardlsum, 2));
        //        map.put("sjdlhj",StringUtils.round(((bnsjdlhjsum / 10000)) + (rfdlsjhj / 10000),2));
        map.put("sjdlhj", StringUtils.round(bnsjdlhjsum / 10000, 2));
        if (yeardlsum != 0) {
            map.put("wcqkhj", StringUtils.round(((bnsjdlhjsum / 10000) / yeardlsum) * 100, 0));
        } else {
            map.put("wcqkhj", 0.0);
        }
        if (kyyeardlsum != 0) {
            map.put("kywcqkhj", StringUtils.round(((bnsjdlhjsum / 10000) / kyyeardlsum) * 100, 0));
        } else {
            map.put("kywcqkhj", 0.0);
        }
        map.put("rzqdhj", StringUtils.round(bnrzqdhjsum, 2));
        map.put("dxxsshj", StringUtils.round(dxxsssum, 0));

        return map;
    }

}
