package com.gyee.runeconomy.service.EarlyWarning;



import com.gyee.runeconomy.dto.AlarmDataParser;
import com.gyee.runeconomy.init.CacheContext;
import com.gyee.runeconomy.model.ProEconAlarmPlan;
import com.gyee.runeconomy.model.ProEconAlarmReal;
import com.gyee.runeconomy.model.ReliabilityIssues;
import com.gyee.runeconomy.model.auto.ProBasicEquipment;
import com.gyee.runeconomy.model.auto.ProBasicPowerstation;
import com.gyee.runeconomy.model.auto.TurbineInfoDay;
import com.gyee.runeconomy.service.auto.ProEconAlarmPlanService;
import com.gyee.runeconomy.service.auto.ProEconAlarmRealService;
import com.gyee.runeconomy.service.auto.ReliabilityIssuesService;
import com.gyee.runeconomy.service.auto.ITurbineInfoDayService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class EarlyWarningReliableService {

    @Resource
    private ProEconAlarmRealService proEconAlarmRealService;
    @Resource
    private ProEconAlarmPlanService proEconAlarmPlanService;
    @Resource
    private ReliabilityIssuesService reliabilityIssuesService;
    @Resource
    private ITurbineInfoDayService turbineInfoDayService;
    public void Electricity() throws Exception {
        ApiClient client = new ApiClient();
        /*********************************************时间处理*********************************/
        // 定义日期格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 减去一个月得到上个月
        LocalDate previousMonthDate = currentDate.minusMonths(1);

        // 格式化上个月的年月
        String time = previousMonthDate.format(inputFormatter);

        // 解析上个月的年月
        YearMonth yearMonth = YearMonth.parse(time, inputFormatter);

        // 获取指定月份的起始和结束日期时间，并转换为字符串
        String startOfMonth = yearMonth.atDay(1).atTime(0, 0, 0).format(outputFormatter); // 上个月的第一天，精确到 00:00:00
        String endOfMonth = yearMonth.atEndOfMonth().atTime(23, 59, 59).format(outputFormatter); // 上个月的最后一天，精确到 23:59:59

//        String startby = "2024-11-01 00:00:00";
//        String startbyjs = "2024-11-30 10:00:00";
        /*********************************************时间处理*********************************/

        List<ProBasicPowerstation> powerstationList = CacheContext.wpls;
        List<ProBasicEquipment> wtlist = CacheContext.wtls;

        for (ProBasicPowerstation p : powerstationList) {
            List<ProBasicEquipment> equipments = wtlist.stream()
                    .filter(w -> p.getId().equals(w.getWindpowerstationId()))
                    .collect(Collectors.toList());

            List<ReliabilityIssues> IssuesList = new ArrayList<>();

            for (ProBasicEquipment equipment : equipments) {
                // 获取月度风机数据
                List<TurbineInfoDay> turbineList = turbineInfoDayService.getTurbineList(equipment.getId(), startOfMonth, endOfMonth);
                int tjcssum = turbineList.stream()
                        .filter(turbine -> turbine.getTjcs() != null)
                        .mapToInt(TurbineInfoDay::getTjcs)
                        .sum();

                // 调用 API 获取预警数据
                String result = client.getDataFromApi(
                        startOfMonth,
                        endOfMonth,
                        equipment.getId(),
                        equipment.getModelId(),
                        "windturbine",
                        "",
                        "h"
                );

                if (result.trim().equals("[]")) {
                    continue; // 无数据则跳过
                }

                // 解析预警数据
                List<AlarmDataParser.AlarmData> response = AlarmDataParser.parseResponse(result);
                if (response.isEmpty()) {
                    continue;
                }

                // 初始化 ReliabilityIssues 对象
                ReliabilityIssues issue = new ReliabilityIssues();
                issue.setStationId(p.getId());
                issue.setTurbineId(equipment.getAname());
                issue.setRecordDate(time);
                issue.setDowntimeCount(tjcssum);
                IssuesList.add(issue);


                // 使用流按部件类型分组，并筛选出每组中count最大的记录
                Map<String, Optional<AlarmDataParser.AlarmData>> groupedData = response.stream()
                        .collect(Collectors.groupingBy(
                                AlarmDataParser.AlarmData::getRelateParts, // 按部件类型分组
                                Collectors.maxBy(Comparator.comparingInt(AlarmDataParser.AlarmData::getCount)) // 按count最大值筛选
                        ));
                // 将筛选出的最大count值的AlarmData重新赋给response
                List<AlarmDataParser.AlarmData> filteredResponse = groupedData.values().stream()
                        .map(Optional::get)
                        .collect(Collectors.toList());

                // 将筛选后的结果赋给原始response
                response.clear(); // 清空原有数据
                response.addAll(filteredResponse); // 将筛选后的数据添加回response

                
                // 处理每条预警数据
                for (AlarmDataParser.AlarmData alarmData : response) {
                    // 查询 Alarmid 对应信息
                    String planId = proEconAlarmRealService.getProEconAlarmReal(alarmData.getAlarmid())
                            .stream()
                            .findFirst()
                            .map(ProEconAlarmReal::getAlarmPlan)
                            .orElse("0");

                    // 查询预警类型和部件类型
                    ProEconAlarmPlan alarmPlan = proEconAlarmPlanService.selectAlarmPlanByProId(planId)
                            .stream()
                            .findFirst()
                            .orElse(null);

                    String yjType = (alarmPlan != null) ? alarmPlan.getTypedetails() : "0";
                    String bjType = (alarmPlan != null) ? alarmPlan.getTypes() : "0";

                    // 提取必要字段
                    String alertText = alarmData.getAlertText();
                    String frequencyHours = alarmData.getCount() + "/" + alarmData.getTime();
                    String relateType = alarmData.getRelateParts();

                    // 根据隐患类型分类处理
                    if ("温度隐患".equals(yjType)) {
                        processTemperatureIssues(issue, relateType, alertText, frequencyHours);
                    } else if ("其它隐患".equals(yjType)) {
                        processOtherIssues(issue, bjType, alertText, frequencyHours);
                    }
                }
            }

            // 计算第一组字段的总频次
            List<ReliabilityIssues> firstSortedIssues = IssuesList.stream()
                    .map(iss -> {
                        double totalFrequency = 0;
                        // 累加原有字段的频次
                        totalFrequency += parseFrequency(iss.getMainShaftFrequencyHours());
                        totalFrequency += parseFrequency(iss.getGeneratorFrequencyHours());
                        totalFrequency += parseFrequency(iss.getGearboxFrequencyHours());
                        totalFrequency += parseFrequency(iss.getPitchSystemFrequencyHours());
                        totalFrequency += parseFrequency(iss.getTemperatureOtherFrequencyHours());

                        // 将计算的总频次存储在临时变量中
                        iss.setReliabilityIssueJs(totalFrequency);  // 存储为double类型的频次总和
                        return iss;
                    })
                    .sorted((i1, i2) -> Double.compare(i2.getReliabilityIssueJs(), i1.getReliabilityIssueJs()))  // 按总频次排序
                    .limit(5)  // 取前五名
                    .collect(Collectors.toList());

            // 计算第二组字段的总频次
            List<ReliabilityIssues> secondSortedIssues = IssuesList.stream()
                    .map(iss -> {
                        double totalFrequency = 0;
                        // 累加新增字段的频次
                        totalFrequency += parseFrequency(iss.getVibrationFrequencyHours());
                        totalFrequency += parseFrequency(iss.getMechanicalFrequencyHours());
                        totalFrequency += parseFrequency(iss.getElectricalFrequencyHours());
                        totalFrequency += parseFrequency(iss.getHydraulicFrequencyHours());
                        totalFrequency += parseFrequency(iss.getWindMeasurementFrequencyHours());
                        totalFrequency += parseFrequency(iss.getOtherFrequencyHours());

                        // 将计算的总频次存储在临时变量中
                        iss.setReliabilityIssueJs(totalFrequency);  // 临时存储频次总和为字符串
                        return iss;
                    })
                    .sorted((i1, i2) -> Double.compare(i2.getReliabilityIssueJs(), i1.getReliabilityIssueJs())) // 按总频次排序
                    .limit(5)  // 取前五名
                    .collect(Collectors.toList());

            // 合并两组数据
//            List<ReliabilityIssues> topTenIssues = new ArrayList<>();
            firstSortedIssues.forEach(iss -> {
                iss.setReliabilityIssue("是");
                iss.setReliabilityIs(1);});

            secondSortedIssues.forEach(isc -> {
                isc.setReliabilityIssue("是");
                // 判断 ReliabilityIs 是否为 1
                if (isc.getReliabilityIs() != null && isc.getReliabilityIs() == 1) {
                    isc.setReliabilityIs(3);  // 如果是 1，设置为 3
                } else {
                    isc.setReliabilityIs(2);  // 否则，设置为 2
                }
            });


//            topTenIssues.addAll(firstSortedIssues);
//            topTenIssues.addAll(secondSortedIssues);
//            // 将 top 10 记录的 reliabilityIssue 设置为 "是"
//            topTenIssues.forEach(iss -> iss.setReliabilityIssue("是"));

            // 将其它数据的 reliabilityIssue 设置为 "否"
            IssuesList.stream()
                    .filter(iss -> !secondSortedIssues.contains(iss) && !firstSortedIssues.contains(iss))  // 排除已经设置为 "是" 的数据
                    .forEach(iss -> iss.setReliabilityIssue("否"));

            // 调用 saveBatch 保存数据
            boolean b = reliabilityIssuesService.saveBatch(IssuesList);
            System.out.println("可靠性问题运行结束");
        }
    }

    // 辅助方法：解析频次字符串并计算总和（如果是 "count/time" 格式）
    private double parseFrequency(String frequency) {
        if (frequency != null && frequency.contains("/")) {
            try {
                String[] parts = frequency.split("/");
                return Double.parseDouble(parts[0]); // 取前面的频次部分
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        return 0;
    }
    /**
     * 处理温度隐患问题
     */
    private void processTemperatureIssues(ReliabilityIssues issue, String relateType, String alertText, String frequencyHours) {
        switch (relateType) {
            case "ZZ":
                issue.setMainShaftType(alertText);
                issue.setMainShaftFrequencyHours(frequencyHours);
                break;
            case "FDJ":
                issue.setGeneratorType(alertText);
                issue.setGeneratorFrequencyHours(frequencyHours);
                break;
            case "CLX":
                issue.setGearboxType(alertText);
                issue.setGearboxFrequencyHours(frequencyHours);
                break;
            case "BJXT":
                issue.setPitchSystemType(alertText);
                issue.setPitchSystemFrequencyHours(frequencyHours);
                break;
            default:
                issue.setTemperatureOtherIssues(alertText);
                issue.setTemperatureOtherFrequencyHours(frequencyHours);
                break;
        }
    }

    /**
     * 处理其它隐患问题
     */
    private void processOtherIssues(ReliabilityIssues issue, String bjType, String alertText, String frequencyHours) {
        switch (bjType) {
            case "ZD":
                issue.setVibrationType(alertText);
                issue.setVibrationFrequencyHours(frequencyHours);
                break;
            case "JX":
                issue.setElectricalType(alertText);
                issue.setElectricalFrequencyHours(frequencyHours);
                break;
            case "YYXT":
                issue.setWindMeasurementType(alertText);
                issue.setWindMeasurementFrequencyHours(frequencyHours);
                break;
            default:
                issue.setOtherIssues(alertText);
                issue.setOtherFrequencyHours(frequencyHours);
                break;
        }
    }

}
