package com.gyee.generation.service;

import com.gyee.common.contant.ContantXk;
import com.gyee.common.model.PointData;
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.ProEconActivePowerData;
import com.gyee.generation.model.auto.ProEconWtPowerCurveFitting;
import com.gyee.generation.model.vo.StatData;
import com.gyee.generation.model.vo.WpType;
import com.gyee.generation.service.auto.IProEconWtPowerCurveFittingService;
import com.gyee.generation.util.DateUtils;
import com.gyee.generation.util.StringUtils;
import com.gyee.generation.util.realtimesource.IEdosUtil;
import org.springframework.stereotype.Service;

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

@Service
public class CoefficientService {

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


    public Map<String, Map<String, Double>> coefficient(String wtId, Date currentDate) throws Exception {

        Date beginDate = DateUtils.addDays(currentDate, -1);


        Calendar c = Calendar.getInstance();
        c.setTime(beginDate);

        c.set(Calendar.DAY_OF_MONTH, 1);
        Date monthbeginDate = c.getTime();
        c.set(Calendar.MONTH, 0);
        Date yearbeginDate = c.getTime();


        Date endDate = currentDate;

        Map<String, Map<String, Double>> resultmap = new HashMap<>();

        ProBasicEquipment wt = CacheContext.wtmap.get(wtId);

        //        //遍历所有风机ID
        //        for (ProBasicEquipment wt : wtls) {

        //****************************************年功率一致性统计********************************************************************/
        List<ProEconActivePowerData> yearList;

        List<ProEconActivePowerData> queryYear = new ArrayList<>();

        Map<String, ProBasicEquipmentPoint> wtpointmap = CacheContext.wtpAimap.get(wt.getId());
        ProBasicEquipmentPoint fspoint = wtpointmap.get(ContantXk.CJ_SSFS);
        List<PointData> fsls = edosUtil.getHistStat(fspoint.getNemCode(), yearbeginDate.getTime() / 1000, endDate.getTime() / 1000, null, 60 * 60L * 6, StatData.AVG.getValue());

        ProBasicEquipmentPoint glpoint = wtpointmap.get(ContantXk.CJ_SSGL);
        List<PointData> glls = edosUtil.getHistStat(glpoint.getNemCode(), yearbeginDate.getTime() / 1000, endDate.getTime() / 1000, null, 60 * 60L * 6, StatData.AVG.getValue());

        if (!fsls.isEmpty() && !glls.isEmpty() && fsls.size() == glls.size()) {
            for (int i = 0; i < fsls.size(); i++) {
                PointData fspd = fsls.get(i);
                PointData glpd = fsls.get(i);
                ProEconActivePowerData po = new ProEconActivePowerData();
                po.setWindturbineId(wt.getId());
                po.setModelId(wt.getModelId());
                po.setWindpowerstationId(wt.getWindpowerstationId());
                po.setFrequency(fsls.size());
                po.setSpeed(StringUtils.round(fspd.getPointValueInDouble(), 2));
                po.setPower(StringUtils.round(glpd.getPointValueInDouble(), 2));
                queryYear.add(po);
            }
        }


        yearList = calCoefficient(queryYear, wt);

        //****************************************月功率一致性统计********************************************************************/

        List<ProEconActivePowerData> monthList;
        List<ProEconActivePowerData> queryMonth = new ArrayList<>();


        fsls = edosUtil.getHistStat(fspoint.getNemCode(), monthbeginDate.getTime() / 1000, endDate.getTime() / 1000, null, 60 * 60L, StatData.AVG.getValue());
        glls = edosUtil.getHistStat(glpoint.getNemCode(), monthbeginDate.getTime() / 1000, endDate.getTime() / 1000, null, 60 * 60L, StatData.AVG.getValue());

        if (!fsls.isEmpty() && !glls.isEmpty() && fsls.size() == glls.size()) {
            for (int i = 0; i < fsls.size(); i++) {
                PointData fspd = fsls.get(i);
                PointData glpd = fsls.get(i);
                ProEconActivePowerData po = new ProEconActivePowerData();
                po.setWindturbineId(wt.getId());
                po.setModelId(wt.getModelId());
                po.setWindpowerstationId(wt.getWindpowerstationId());
                po.setFrequency(fsls.size());
                po.setSpeed(StringUtils.round(fspd.getPointValueInDouble(), 2));
                po.setPower(StringUtils.round(glpd.getPointValueInDouble(), 2));
                queryMonth.add(po);
            }
        }


        monthList = calCoefficient(queryMonth, wt);


        //*****************************************日功率一致性统计********************************************************************/


        List<ProEconActivePowerData> dayList;


        List<ProEconActivePowerData> queryDay = new ArrayList<>();


        fsls = edosUtil.getHistStat(fspoint.getNemCode(), beginDate.getTime() / 1000, endDate.getTime() / 1000, null, 900L, StatData.AVG.getValue());
        glls = edosUtil.getHistStat(glpoint.getNemCode(), beginDate.getTime() / 1000, endDate.getTime() / 1000, null, 900L, StatData.AVG.getValue());

        if (!fsls.isEmpty() && !glls.isEmpty() && fsls.size() == glls.size()) {
            for (int i = 0; i < fsls.size(); i++) {
                PointData fspd = fsls.get(i);
                PointData glpd = fsls.get(i);
                ProEconActivePowerData po = new ProEconActivePowerData();
                po.setWindturbineId(wt.getId());
                po.setModelId(wt.getModelId());
                po.setWindpowerstationId(wt.getWindpowerstationId());
                po.setFrequency(fsls.size());
                po.setSpeed(StringUtils.round(fspd.getPointValueInDouble(), 2));
                po.setPower(StringUtils.round(glpd.getPointValueInDouble(), 2));
                queryDay.add(po);
            }
        }
        dayList = calCoefficient(queryDay, wt);


        Double resultYear = coefficient(yearList, currentDate, wt.getId());
        Double resultMonth = coefficient(monthList, currentDate, wt.getId());
        Double resultDay = coefficient(dayList, currentDate, wt.getId());

        Map<String, Double> tempmap = new HashMap<>();
        tempmap.put("year", resultYear);
        tempmap.put("month", resultMonth);
        tempmap.put("day", resultDay);
        resultmap.put(wt.getId(), tempmap);

        //        }


        return resultmap;
    }


    private List<ProEconActivePowerData> calCoefficient(List<ProEconActivePowerData> query, ProBasicEquipment wt) {


        Map<Double, List<ProEconActivePowerData>> apdataYearMap = query.stream().collect(Collectors.groupingBy(ProEconActivePowerData::getSpeed));


        Map<Double, Double> speedAndPowerYearMap = new HashMap<>();
        apdataYearMap.forEach((key, value) -> {
            DoubleSummaryStatistics summaryStatistics = value.stream().mapToDouble(ProEconActivePowerData::getPower).summaryStatistics();
            speedAndPowerYearMap.put(key, summaryStatistics.getAverage());
        });

        List<ProEconActivePowerData> yearList = new ArrayList<>();


        speedAndPowerYearMap.forEach((key, value) -> {

            ProEconActivePowerData activepowerdata = new ProEconActivePowerData();
            activepowerdata.setWindturbineId(wt.getId());
            activepowerdata.setSpeed(key);
            activepowerdata.setPower(value);
            activepowerdata.setFrequency(1);
            activepowerdata.setModelId(wt.getModelId());

            yearList.add(activepowerdata);
        });

        return yearList;

    }


    //功率一致性系数
    private Double coefficient(List<ProEconActivePowerData> dataList, Date currentDate, String windturbineId) {
        double result = 0.0;
        double count = 0.0;

        if (dataList != null && dataList.size() != 0) {


            Calendar c = Calendar.getInstance();
            c.setTime(currentDate);

            //            QueryWrapper<ProEconWtPowerCurveFitting> queryWrapper = new QueryWrapper<>();
            //            queryWrapper.eq("windturbine_id",windturbineId);
            //            powerList = proEconWtPowerCurveFittingService.list(queryWrapper);


            Map<Double, ProEconWtPowerCurveFitting> curveFittingPowerMap = null;
            if (CacheContext.curveFittingPowerMap.containsKey(windturbineId)) {
                curveFittingPowerMap = CacheContext.curveFittingPowerMap.get(windturbineId);

            }

            for (ProEconActivePowerData data : dataList) {
                Double p1 = data.getPower();
                Double speed = data.getSpeed();
                //                if (speed < 3 || speed > 25) {
                //                    continue;
                //                }

                if (CacheContext.wtmap.containsKey(windturbineId)) {
                    ProBasicEquipment wt = CacheContext.wtmap.get(windturbineId);

                    if (wt.getWindpowerstationId().contains(WpType.GDC.id)) {
                        speed /= 100;
                        speed = StringUtils.round(speed, 2);
                        speed *= 100;

                        speed = StringUtils.round(speed, 2);
                    } else {
                        speed = StringUtils.round(speed, 2);
                    }
                }


                if (CacheContext.theoreticalPowerMap.containsKey(data.getModelId())) {
                    if (CacheContext.theoreticalPowerMap.get(data.getModelId()).size() > 0) {
                        if (CacheContext.theoreticalPowerMap.get(data.getModelId()).containsKey(speed)) {
                            Double p = CacheContext.theoreticalPowerMap.get(data.getModelId()).get(speed).getEnsurePower();


                            if (p != 0) {
                                for (int i = 0; i < data.getFrequency(); i++) {
                                    result += Math.abs((p - p1) / p);
                                    count += 1;
                                }
                            }
                        }
                    } else {
                        if (null != curveFittingPowerMap && curveFittingPowerMap.containsKey(speed)) {
                            double optimalPower = curveFittingPowerMap.get(speed).getOptimalPower();

                            if (optimalPower != 0) {
                                for (int i = 0; i < data.getFrequency(); i++) {
                                    result += Math.abs((optimalPower - p1) / optimalPower);
                                    count += 1;
                                }
                            }

                        } else {


                            DoubleSummaryStatistics summaryStatistics = curveFittingPowerMap.entrySet()
                                    .stream()
                                    .collect(Collectors.summarizingDouble(Map.Entry::getKey));
                            double max = summaryStatistics.getMax();
                            if (speed > max) {

                                double actualPower = curveFittingPowerMap.get(speed).getActualPower();

                                if (actualPower != 0.0) {

                                    for (int i = 0; i < data.getFrequency(); i++) {
                                        result += Math.abs((actualPower - p1) / actualPower);
                                        count += 1;
                                    }
                                }
                            }

                        }
                    }
                }

            }
            if (count != 0)
                result = result / count * 100;
            else
                result = 100.0;
        }

        return result;

    }
}


