package com.gyee.runeconomy.service.WindDirection;


import com.gyee.common.contant.ContantXk;
import com.gyee.runeconomy.init.CacheContext;
import com.gyee.runeconomy.model.auto.*;
import com.gyee.runeconomy.model.vo.WindData;
import com.gyee.runeconomy.service.auto.IProBasicEquipmentPointService;
import com.gyee.runeconomy.service.auto.IProBasicPowerstationPointService;
import com.gyee.runeconomy.service.auto.ITurbineInfoDayService;
import com.gyee.runeconomy.util.DateUtils;
import com.gyee.runeconomy.util.realtimesource.feign.RemoteServiceBuilder;
import com.gyee.runeconomy.util.realtimesource.feign.TsDoubleData;
import org.springframework.stereotype.Service;

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

@Service
public class WindMachineJsService {

    @Resource
    private IProBasicEquipmentPointService proBasicEquipmentPointService;
    @Resource
    private IProBasicPowerstationPointService proBasicPowerstationPointService;
    @Resource
    private RemoteServiceBuilder remoteService;
    @Resource
    private ITurbineInfoDayService turbineInfoDayService;


    public Object machine(String wpid,String time) throws Exception {

        //查询时间-开始结束
        String[] timeRange = DateUtils.generateTimeRange(time);
        String kssj = timeRange[0];
        String jssj = timeRange[1];

        Date[] sjcl = DateUtils.sjcl(kssj, jssj);

        // 获取 startDate 和 endDate
        Date startDate = sjcl[0];
        Date endDate = sjcl[1];

        Map<String, Object> map = new HashMap<>();

        List<WindData> list = new ArrayList<>();
        List<ProBasicEquipment> collect = CacheContext.wtls.stream()
                .filter(wt -> wpid.equals(wt.getWindpowerstationId()))
                .collect(Collectors.toList());

        List<ProBasicWeatherStation> subStations = CacheContext.weawpls.stream()
                .filter(ws -> wpid.equals(ws.getWindpowerstationId()))
                .collect(Collectors.toList());
        String weaStation = subStations.isEmpty() ? "NX_FGS_HA01_WS" : subStations.get(0).getId();

        // 初始化场站点
        String finalWeaStation = weaStation;
        Map<stationtype, ProBasicPowerstationPoint> czpoints = Arrays.stream(stationtype.values())
                .collect(Collectors.toMap(type -> type, type -> getpowerstationPoint(finalWeaStation, type)));

        // 获取场站点的历史数据
        Map<stationtype, TsDoubleData> czhistoryData = czpoints.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> getczSortedHistory(entry.getValue(), startDate.getTime(), endDate.getTime())));

        //风机循环取数
        for (ProBasicEquipment eq : collect) {
            // 初始化设备点
            Map<EquipmentPointType, ProBasicEquipmentPoint> points = Arrays.stream(EquipmentPointType.values())
                    .collect(Collectors.toMap(type -> type, type -> getEquipmentPoint(eq.getId(), type)));

            // 获取设备点的历史数据
            Map<EquipmentPointType, TsDoubleData> historyData = points.entrySet().stream()
                    .collect(Collectors.toMap(Map.Entry::getKey, entry -> getSortedHistory(entry.getValue(), startDate.getTime(), endDate.getTime())));

            WindData wd = new WindData();
            wd.setWtid(eq.getId());

            // 获取历史数据
            TsDoubleData fs = historyData.get(EquipmentPointType.PJFS);
            TsDoubleData fx = historyData.get(EquipmentPointType.PJFX);
            TsDoubleData cftfs = czhistoryData.get(stationtype.FCCFTFS90);
            TsDoubleData cftfx = czhistoryData.get(stationtype.FCCFTFX90);

            // 计算偏差，若某个数据为空则默认为 1.0
            double fspc = Deviation.calculateSpeedDeviation(
                    Optional.ofNullable(fs).map(TsDoubleData::getDoubleValue).orElse(1.0),
                    Optional.ofNullable(cftfs).map(TsDoubleData::getDoubleValue).orElse(1.0)
            );
            double fxpc = Deviation.calculateDirectionDeviation(
                    Optional.ofNullable(fx).map(TsDoubleData::getDoubleValue).orElse(1.0),
                    Optional.ofNullable(cftfx).map(TsDoubleData::getDoubleValue).orElse(1.0)
            );

            // 设置 WindData 对象的属性
            wd.setFanSpeed(Optional.ofNullable(fs).map(TsDoubleData::getDoubleValue).orElse(1.0));
            wd.setTowerSpeed(Optional.ofNullable(cftfs).map(TsDoubleData::getDoubleValue).orElse(1.0));
            wd.setPcSpeed(fspc);

            wd.setFanDirection(Optional.ofNullable(fx).map(TsDoubleData::getDoubleValue).orElse(1.0));
            wd.setTowerDirection(Optional.ofNullable(cftfx).map(TsDoubleData::getDoubleValue).orElse(1.0));
            wd.setPcDirection(fxpc);

            list.add(wd);
        }

        return list;
    }


    // 工具方法：获取设备点
    private ProBasicEquipmentPoint getEquipmentPoint(String wtid, EquipmentPointType type) {
        return proBasicEquipmentPointService.getEquipmentPoint(wtid, type.getCode());
    }
    // 工具方法：获取设备点
    private ProBasicPowerstationPoint getpowerstationPoint(String wpid, stationtype type) {
        return proBasicPowerstationPointService.getPowerstationPoint(wpid, type.getCode());
    }

    // 工具方法：获取风机历史数据
    private TsDoubleData getSortedHistory(ProBasicEquipmentPoint point, long startTime, long endTime) {
        if (point == null) return null;
        Map<String, TsDoubleData> historyStat = remoteService.adapterfd().getHistoryStat(point.getNemCode(), startTime, endTime);
        TsDoubleData avg = historyStat.get("avg");
        return avg;
    }
    // 工具方法：获取风机历史数据
    private TsDoubleData getczSortedHistory(ProBasicPowerstationPoint point, long startTime, long endTime) {
        if (point == null) return null;
        Map<String, TsDoubleData> data = remoteService.adapterfd().getHistoryStat(point.getNemCode(), startTime, endTime);
        TsDoubleData avg = data.get("avg");
        return avg;
    }
    // 枚举定义
    public enum EquipmentPointType {
        PJFS(ContantXk.CJ_SSFS),
        PJFX(ContantXk.CJ_FX);

        private final String code;

        EquipmentPointType(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }
    }
    // 枚举定义
    public enum stationtype {
        FCCFTFS90(ContantXk.FCCFTFS90),
        FCCFTFX90(ContantXk.FCCFTFX90);

        private final String code;

        stationtype(String code) {
            this.code = code;
        }

        public String getCode() {
            return code;
        }
    }
}
