package com.gyee.runeconomy.service.Comprehensive;

import com.gyee.common.contant.ContantXk;
import com.gyee.common.model.StringUtils;
import com.gyee.common.util.DateUtils;
import com.gyee.runeconomy.init.CacheContext;
import com.gyee.runeconomy.model.auto.*;
import com.gyee.runeconomy.service.auto.IProBasicPowerstationPointService;
import com.gyee.runeconomy.service.auto.IProEconEquipmentInfoDay1Service;
import com.gyee.runeconomy.service.auto.IProEconPowerstationInfoDay1Service;
import com.gyee.runeconomy.service.auto.IProEconPowerstationInfoDay5Service;
import com.gyee.runeconomy.service.auto.impl.ProEconSystemEfficiencyEquipmentServiceImpl;
import com.gyee.runeconomy.service.auto.impl.ProEconSystemEfficiencyServiceImpl;
import com.gyee.runeconomy.util.realtimesource.IEdosUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PVSystemEfficiencyCalculator {
    @Resource
    private IProEconPowerstationInfoDay5Service proEconPowerstationInfoDay5Service;
    @Resource
    private IProEconPowerstationInfoDay1Service proEconPowerstationInfoDay1Service;

    @Resource
    private IProEconEquipmentInfoDay1Service proEconEquipmentInfoDay1Service;

    @Resource
    private ProEconSystemEfficiencyServiceImpl systemEfficiencyService;

    @Resource
    private ProEconSystemEfficiencyEquipmentServiceImpl efficiencyEquipmentService;

    @Resource
    private IProBasicPowerstationPointService proBasicPowerstationPointService;

    @Resource
    private IEdosUtil edosUtil;

    public void planvalue() throws Exception {

        String year = "2023";
        //参数所传年份
        int currentyear = Integer.parseInt(year);

        int ts = 1;

        Calendar cal = Calendar.getInstance();
        int dqnf = cal.get(Calendar.YEAR);//本年

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

        // 初始化初始值
        Date initialFirstDayZeroHour = (Date) firstDayZeroHour.clone();
        // 获取firstDayZeroHour的月份
        Calendar calFirstDayZeroHour = Calendar.getInstance();
        calFirstDayZeroHour.setTime(firstDayZeroHour);
        int calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;

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

        List<ProBasicPowerstation> wplsG = CacheContext.wplsG;
        List<ProBasicProject> pjlsG = CacheContext.pjls.stream().filter(p -> p.getSpare4().equals("2")).collect(Collectors.toList());
        List<ProBasicLine> lnlsG = CacheContext.lnls.stream().filter(p -> p.getSpare4().equals("2")).collect(Collectors.toList());
        //        List<ProBasicEquipment> wtlsG = CacheContext.wtls.stream().filter(p -> p.getSpare1().equals("IN")).collect(Collectors.toList());


        //        计算场站级别
        for (ProBasicPowerstation wp : wplsG) {

            for (int i = 0; i < currentMonth; i++) {

                Date date = null;
                List<ProEconSystemEfficiency> stringList = new ArrayList<>();

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

                double rfdlsj = 0.0;
                List<ProEconPowerstationInfoDay5> day5List = proEconPowerstationInfoDay5Service.getmax(wp.getId(), firstDayZeroHour);

                List<ProEconPowerstationInfoDay1> rzqdls = proEconPowerstationInfoDay1Service.getmax(wp.getId(), firstDayZeroHour);

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

                double solarRadiationWattsPerSquareMeter = 0.0; // 太阳能辐射，单位为W/m²
                double actualPowerOutputKilowattHours = 0.0; // 实际发电量，单位为千瓦时(kWh)
                double moduleCapacityKilowatts = 0.0; // 光伏模块额定容量，单位为千瓦(kW)
                double pr = 0.0;
                if (!day5List.isEmpty() && day5List != null) {
                    for (ProEconPowerstationInfoDay5 day : day5List) {
                        if (calFirstMonth == currentMonth) {
                            actualPowerOutputKilowattHours = day.getYfdldb().doubleValue() + rfdlsj;
                        } else {
                            actualPowerOutputKilowattHours = day.getYfdldb().doubleValue();
                        }
                        date = day.getRecordDate();
                    }
                }
                if (!rzqdls.isEmpty() && rzqdls != null) {
                    for (ProEconPowerstationInfoDay1 rz : rzqdls) {
                        solarRadiationWattsPerSquareMeter = rz.getYpjfs().doubleValue();
                    }
                }
                moduleCapacityKilowatts = wp.getJrCapacity();

                double expectedPowerOutputKilowattHours = calculateExpectedPowerOutput(solarRadiationWattsPerSquareMeter, moduleCapacityKilowatts, ts); // 预期发电量（kWh）
                pr = calculatePR(actualPowerOutputKilowattHours, expectedPowerOutputKilowattHours); // 计算PR

                //                DecimalFormat decimalFormat = new DecimalFormat("#");
                //                String formattedResult = decimalFormat.format(pr);
                pr = StringUtils.round(pr, 2);

                solarRadiationWattsPerSquareMeter = StringUtils.round(solarRadiationWattsPerSquareMeter, 2);

                //                System.out.println("太阳能辐射: " + solarRadiationWattsPerSquareMeter + " W/m²");
                //                System.out.println("实际发电量: " + actualPowerOutputKilowattHours + " kWh");
                //                System.out.println("光伏模块额定容量: " + moduleCapacityKilowatts + " kW");
                //                System.out.println("预期发电量: " + expectedPowerOutputKilowattHours + " kWh");
                //                System.out.println("光伏系统效率 (PR): " + pr + "%");

                ProEconSystemEfficiency power = new ProEconSystemEfficiency();
                power.setId(StringUtils.getUUID());
                power.setForeignKeyId(wp.getId());
                power.setStationId(wp.getId());
                power.setLocation("wp");
                power.setDataDate(date);
                power.setRzqd(solarRadiationWattsPerSquareMeter);
                power.setEfficiency(pr);
                stringList.add(power);
                systemEfficiencyService.batchAdd(stringList);

                firstDayZeroHour = DateUtils.addMonths(firstDayZeroHour, 1);
                calFirstDayZeroHour.setTime(firstDayZeroHour);
                calFirstMonth = calFirstDayZeroHour.get(Calendar.MONTH) + 1;
                ts = calFirstDayZeroHour.getActualMaximum(Calendar.DAY_OF_MONTH);
            }
            // 恢复初始值
            firstDayZeroHour = initialFirstDayZeroHour;
        }

        //        计算期次级别
        int ts2 = 1; // 设置为本年一月一号0点

        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(new Date());
        calendar2.set(Calendar.YEAR, currentyear); // 根据当前年份变化
        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 firstDayZeroHour2 = calendar2.getTime();

        // 初始化初始值
        Date initialFirstDayZeroHour2 = (Date) firstDayZeroHour2.clone();

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

        for (ProBasicProject pj : pjlsG) {
            for (int i = 0; i < currentMonth; i++) {
                Date date = null;
                List<ProEconSystemEfficiency> stringList = new ArrayList<>();

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

                double rfdlsj = 0.0;
                List<ProEconPowerstationInfoDay5> day5List = proEconPowerstationInfoDay5Service.getmax(pj.getId(), firstDayZeroHour2);
                List<ProEconPowerstationInfoDay1> rzqdls = proEconPowerstationInfoDay1Service.getmax(pj.getId(), firstDayZeroHour2);
                ProBasicPowerstationPoint rfdlvalue = proBasicPowerstationPointService.getPowerstationPoint(pj.getId(), ContantXk.RFDL);
                rfdlsj = edosUtil.getRealData(rfdlvalue).getPointValueInDouble();
                double solarRadiationWattsPerSquareMeter = 0.0; // 太阳能辐射，单位为W/m²
                double actualPowerOutputKilowattHours = 0.0; // 实际发电量，单位为千瓦时(kWh)
                double moduleCapacityKilowatts = 0.0; // 光伏模块额定容量，单位为千瓦(kW)
                double pr = 0.0;

                if (!day5List.isEmpty() && day5List != null) {
                    for (ProEconPowerstationInfoDay5 day : day5List) {
                        if (calFirstMonth2 == currentMonth && dqnf == currentyear) {
                            actualPowerOutputKilowattHours = day.getYfdldb().doubleValue() + rfdlsj;
                        } else {
                            actualPowerOutputKilowattHours = day.getYfdldb().doubleValue();
                        }
                        date = day.getRecordDate();
                    }
                }

                if (!rzqdls.isEmpty() && rzqdls != null) {
                    for (ProEconPowerstationInfoDay1 rz : rzqdls) {
                        solarRadiationWattsPerSquareMeter = rz.getYpjfs().doubleValue();
                    }
                }

                moduleCapacityKilowatts = pj.getCapacity();

                double expectedPowerOutputKilowattHours = calculateExpectedPowerOutput(solarRadiationWattsPerSquareMeter, moduleCapacityKilowatts, ts2); // 预期发电量（kWh）
                pr = calculatePR(actualPowerOutputKilowattHours, expectedPowerOutputKilowattHours); // 计算PR

                pr = StringUtils.round(pr, 2);
                solarRadiationWattsPerSquareMeter = StringUtils.round(solarRadiationWattsPerSquareMeter, 2);


                ProEconSystemEfficiency power = new ProEconSystemEfficiency();
                power.setId(StringUtils.getUUID());
                power.setForeignKeyId(pj.getId());
                power.setStationId(pj.getWindpowerstationId());
                power.setLocation("pj");
                power.setDataDate(date);
                power.setRzqd(solarRadiationWattsPerSquareMeter);
                power.setEfficiency(pr);
                stringList.add(power);
                systemEfficiencyService.batchAdd(stringList);


                firstDayZeroHour2 = DateUtils.addMonths(firstDayZeroHour2, 1);
                calFirstDayZeroHour2.setTime(firstDayZeroHour2);
                calFirstMonth2 = calFirstDayZeroHour2.get(Calendar.MONTH) + 1;
                ts2 = calFirstDayZeroHour2.getActualMaximum(Calendar.DAY_OF_MONTH);
            }
            // 恢复初始值
            firstDayZeroHour2 = initialFirstDayZeroHour2;
        }


        //计算线路级别
        int ts3 = 1; // 设置为本年一月一号0点

        Calendar calendar3 = Calendar.getInstance();
        calendar3.setTime(new Date());
        calendar3.set(Calendar.YEAR, currentyear); // 根据当前年份变化
        calendar3.set(Calendar.MONTH, Calendar.JANUARY); // 0表示一月
        calendar3.set(Calendar.DAY_OF_MONTH, 1);
        calendar3.set(Calendar.HOUR_OF_DAY, 0);
        calendar3.set(Calendar.MINUTE, 0);
        calendar3.set(Calendar.SECOND, 0);
        calendar3.set(Calendar.MILLISECOND, 0);
        Date firstDayZeroHour3 = calendar3.getTime();

        // 初始化初始值
        Date initialFirstDayZeroHour3 = (Date) firstDayZeroHour3.clone();

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

        for (ProBasicLine ln : lnlsG) {
            List<ProBasicProject> wpid = pjlsG.stream().filter(l -> l.getId().equals(ln.getProjectId())).collect(Collectors.toList());
            for (int i = 0; i < currentMonth; i++) {
                Date date = null;
                List<ProEconSystemEfficiency> stringList = new ArrayList<>();

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

                List<ProEconPowerstationInfoDay5> day5List = proEconPowerstationInfoDay5Service.getmax(ln.getId(), firstDayZeroHour3);
                List<ProEconPowerstationInfoDay1> rzqdls = proEconPowerstationInfoDay1Service.getmax(ln.getId(), firstDayZeroHour3);

                double solarRadiationWattsPerSquareMeter = 0.0; // 太阳能辐射，单位为W/m²
                double actualPowerOutputKilowattHours = 0.0; // 实际发电量，单位为千瓦时(kWh)
                double moduleCapacityKilowatts = 0.0; // 光伏模块额定容量，单位为千瓦(kW)
                double pr = 0.0;

                if (!day5List.isEmpty() && day5List != null) {
                    for (ProEconPowerstationInfoDay5 day : day5List) {
                        actualPowerOutputKilowattHours = day.getYfdldb().doubleValue();
                        date = day.getRecordDate();
                    }
                }

                if (!rzqdls.isEmpty() && rzqdls != null) {
                    for (ProEconPowerstationInfoDay1 rz : rzqdls) {
                        solarRadiationWattsPerSquareMeter = rz.getYpjfs().doubleValue();
                    }
                }

                moduleCapacityKilowatts = ln.getCapacity();

                double expectedPowerOutputKilowattHours = calculateExpectedPowerOutput(solarRadiationWattsPerSquareMeter, moduleCapacityKilowatts, ts3); // 预期发电量（kWh）
                pr = calculatePR(actualPowerOutputKilowattHours, expectedPowerOutputKilowattHours); // 计算PR

                pr = StringUtils.round(pr, 2);
                solarRadiationWattsPerSquareMeter = StringUtils.round(solarRadiationWattsPerSquareMeter, 2);


                ProEconSystemEfficiency power = new ProEconSystemEfficiency();
                power.setId(StringUtils.getUUID());
                power.setForeignKeyId(ln.getId());
                power.setStationId(wpid.get(0).getWindpowerstationId());
                power.setProjectId(wpid.get(0).getId());
                power.setLineId(ln.getId());
                power.setLocation("ln");
                power.setDataDate(date);
                power.setRzqd(solarRadiationWattsPerSquareMeter);
                power.setEfficiency(pr);
                stringList.add(power);
                if (date != null) {
                    systemEfficiencyService.batchAdd(stringList);
                }


                firstDayZeroHour3 = DateUtils.addMonths(firstDayZeroHour3, 1);
                calFirstDayZeroHour3.setTime(firstDayZeroHour3);
                calFirstMonth3 = calFirstDayZeroHour3.get(Calendar.MONTH) + 1;
                ts3 = calFirstDayZeroHour3.getActualMaximum(Calendar.DAY_OF_MONTH);
            }
            // 恢复初始值
            firstDayZeroHour3 = initialFirstDayZeroHour3;
        }


        //计算设备级别
        int ts4 = 1; // 设置为本年一月一号0点

        //        Calendar calendar4 = Calendar.getInstance();
        //        calendar4.setTime(new Date());
        //        calendar4.set(Calendar.YEAR, currentyear); // 根据当前年份变化
        //        calendar4.set(Calendar.MONTH, Calendar.JANUARY); // 0表示一月
        //        calendar4.set(Calendar.DAY_OF_MONTH, 1);
        //        calendar4.set(Calendar.HOUR_OF_DAY, 0);
        //        calendar4.set(Calendar.MINUTE, 0);
        //        calendar4.set(Calendar.SECOND, 0);
        //        calendar4.set(Calendar.MILLISECOND, 0);
        //        Date firstDayZeroHour4 = calendar4.getTime();

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

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

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

        // 设置 beginDate 为前一天的0点
        calendar4.add(Calendar.DAY_OF_MONTH, -1);
        Date firstDayZeroHour4 = calendar4.getTime();

        // 初始化初始值
        Date initialFirstDayZeroHour4 = (Date) firstDayZeroHour4.clone();

        // 获取firstDayZeroHour的月份
        Calendar calFirstDayZeroHour4 = Calendar.getInstance();
        calFirstDayZeroHour4.setTime(firstDayZeroHour4);
        int calFirstMonth4 = calFirstDayZeroHour4.get(Calendar.MONTH) + 1;
        Date date = null;
        List<ProEconSystemEfficiencyEquipment> stringList = new ArrayList<>();
        for (ProBasicPowerstation wp : CacheContext.wplsG) {

            List<ProBasicEquipment> wtlsG = CacheContext.wtls.stream().filter(p -> p.getSpare1().equals("IN") && wp.getId().equals(p.getWindpowerstationId())).collect(Collectors.toList());

            for (ProBasicEquipment wt : wtlsG) {

                List<ProEconEquipmentmodel> collect = CacheContext.equipmentmodels.stream().filter(w -> wt.getModelId().equals(w.getId())).collect(Collectors.toList());

                //            for (int i = 0; i < currentMonth; i++) {


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

                List<ProEconEquipmentInfoDay1> rzqdls = proEconEquipmentInfoDay1Service.getmax(wt.getId(), firstDayZeroHour4);

                double solarRadiationWattsPerSquareMeter = 0.0; // 太阳能辐射，单位为W/m²
                double actualPowerOutputKilowattHours = 0.0; // 实际发电量，单位为千瓦时(kWh)
                double moduleCapacityKilowatts = 0.0; // 光伏模块额定容量，单位为千瓦(kW)
                double pr = 0.0;

                if (!rzqdls.isEmpty() && rzqdls != null) {
                    for (ProEconEquipmentInfoDay1 day : rzqdls) {
                        actualPowerOutputKilowattHours = day.getYfdl().doubleValue();
                        solarRadiationWattsPerSquareMeter = day.getYpjfs().doubleValue();
                        date = day.getRecordDate();
                    }
                }


                moduleCapacityKilowatts = collect.get(0).getPowerProduction();

                double expectedPowerOutputKilowattHours = calculateExpectedPowerOutput(solarRadiationWattsPerSquareMeter, moduleCapacityKilowatts, ts4); // 预期发电量（kWh）
                pr = calculatePR(actualPowerOutputKilowattHours, expectedPowerOutputKilowattHours); // 计算PR

                pr = StringUtils.round(pr, 2);
                solarRadiationWattsPerSquareMeter = StringUtils.round(solarRadiationWattsPerSquareMeter, 2);


                ProEconSystemEfficiencyEquipment power = new ProEconSystemEfficiencyEquipment();
                if (date != null) {
                    power.setId(StringUtils.getUUID());
                    power.setForeignKeyId(wt.getNemCode());
                    power.setStationId(wt.getWindpowerstationId());
                    power.setProjectId(wt.getProjectId());
                    power.setLineId(wt.getLineId());
                    power.setEquipmentId(wt.getId());
                    power.setLocation("wt");
                    power.setDataDate(date);
                    power.setPowerGeneration(actualPowerOutputKilowattHours);
                    power.setLlfdlmax(expectedPowerOutputKilowattHours);
                    power.setRzqd(solarRadiationWattsPerSquareMeter);
                    power.setEfficiency(pr);
                    power.setOrderNum(wt.getOrderNum());
                    stringList.add(power);
                }


                //
                //            firstDayZeroHour4 = DateUtils.addMonths(firstDayZeroHour4, 1);
                //            calFirstDayZeroHour4.setTime(firstDayZeroHour4);
                //            calFirstMonth4 = calFirstDayZeroHour4.get(Calendar.MONTH) + 1;
                ts4 = calFirstDayZeroHour4.getActualMaximum(Calendar.DAY_OF_MONTH);
                //        }
                // 恢复初始值
                //            firstDayZeroHour4 = initialFirstDayZeroHour4;
            }
            efficiencyEquipmentService.batchAdd(stringList);
            stringList.clear();
        }


    }

    // 计算预期发电量的方法
    public static double calculateExpectedPowerOutput(double solarRadiationWattsPerSquareMeter, double moduleCapacityKilowatts, double ts) {
        double hoursOfDaylight = 12.0; // 假设日照时间为12小时
        //辐照度*容量
        //
        return (solarRadiationWattsPerSquareMeter * moduleCapacityKilowatts);
    }

    // 计算光伏系统效率PR的方法
    public static double calculatePR(double actualPowerOutputKilowattHours, double expectedPowerOutputKilowattHours) {
        if (expectedPowerOutputKilowattHours == 0) {
            return actualPowerOutputKilowattHours;
        }
        // 实际发电量/预期发电量
        return (actualPowerOutputKilowattHours / expectedPowerOutputKilowattHours) * 100;
    }
}
