package com.yfd.platform.modules.algorithm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfd.platform.modules.algorithm.domain.AlgorithmDevice;
import com.yfd.platform.modules.algorithm.mapper.AlgorithmDeviceMapper;
import com.yfd.platform.modules.algorithm.service.IAlgorithmDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.auxcontrol.domain.DeviceSignal;
import com.yfd.platform.modules.auxcontrol.domain.DeviceWorkData;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService;
import com.yfd.platform.modules.basedata.domain.SubstationDevice;
import com.yfd.platform.modules.basedata.mapper.SubstationDeviceMapper;
import com.yfd.platform.modules.patroltask.domain.TaskResult;
import com.yfd.platform.modules.patroltask.mapper.TaskResultMapper;
import com.yfd.platform.utils.SecurityUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhengsl
 * @since 2025-05-13
 */
@Service
public class AlgorithmDeviceServiceImpl extends ServiceImpl<AlgorithmDeviceMapper, AlgorithmDevice> implements IAlgorithmDeviceService {

    @Resource
    private AlgorithmDeviceMapper algorithmDeviceMapper;
    @Resource
    private DeviceSignalMapper deviceSignalMapper;
    @Resource
    private IDeviceWorkDataService deviceWorkDataService;
    @Resource
    private TaskResultMapper taskResultMapper;
    @Resource
    private SubstationDeviceMapper substationDeviceMapper;

    /**********************************
     * 用途说明: 批量新增算法分类部件点位关联数据
     * 参数说明 algorithmDeviceList
     * 返回值说明: boolean
     ***********************************/
    @Override
    public boolean batchAddAlgorithmDevice(List<AlgorithmDevice> algorithmDeviceList) {
        LocalDateTime now = LocalDateTime.now();
        algorithmDeviceList.forEach(a -> {
            a.setLastmodifier(SecurityUtils.getCurrentUsername());
            a.setLastmodifydate(now);
        });
        return this.saveOrUpdateBatch(algorithmDeviceList);
    }

    /**********************************
     * 用途说明: 查询算法部件的参数
     * 参数说明 algorithmId 算法分类Id
     * 参数说明 componentId 部件id
     * 返回值说明: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     ***********************************/
    @Override
    public List<Map<String, Object>> getAlgorithmDeviceParams(String algorithmId, String componentId) {
        return algorithmDeviceMapper.getAlgorithmDeviceParams(algorithmId, componentId);
    }

    /**********************************
     * 用途说明: 查询算法部件的参数曲线
     * 参数说明 algorithmId 算法分类Id
     * 参数说明 componentId 部件id
     * 返回值说明: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     ***********************************/
    @Override
    public List<Map<String, Object>> getAlgorithmDeviceCurve(String algorithmId, String componentId) {
        List<Map<String, Object>> list = algorithmDeviceMapper.getAlgorithmDeviceType(algorithmId, componentId);
        Map<String, List<String>> groupedDevices = list.stream()
                .filter(map -> map.containsKey("sourceType") && map.get("sourceType") != null)
                .filter(map -> map.containsKey("deviceId") && map.get("deviceId") != null)
                .collect(Collectors.groupingBy(
                        map -> ((String) map.get("sourceType")).trim(), // 去除前后空格
                        Collectors.mapping(
                                map -> ((String) map.get("deviceId")).trim(),
                                Collectors.toList() // 或 Collectors.toSet() 去重
                        )
                ));
        List<Map<String, Object>> deviceDataList = new ArrayList<>();
        List<String> deviceIdList = groupedDevices.get("1");
        List<String> signalIdList = groupedDevices.get("2");
        if (deviceIdList != null && deviceIdList.size() > 0) {
            List<TaskResult> deviceWorkDataList = taskResultMapper.getResultCurveData(deviceIdList);
            Map<String, List<TaskResult>> collect =
                    deviceWorkDataList.stream().collect(Collectors.groupingBy(TaskResult::getDeviceId));
            for (String deviceId : collect.keySet()) {
                List<TaskResult> taskResults = collect.get(deviceId);
                Map<String, Object> map = processDeviceData(taskResults, deviceId);
                deviceDataList.add(map);
            }
        }
        if (signalIdList != null && signalIdList.size() > 0) {
            List<DeviceWorkData> deviceWorkDataList = deviceWorkDataService.getHistoricalCurveList(signalIdList);
            Map<String, List<DeviceWorkData>> collect =
                    deviceWorkDataList.stream().collect(Collectors.groupingBy(DeviceWorkData::getSignalId));

            for (String signalId : signalIdList) {
                List<DeviceWorkData> deviceWorkDataGroup = collect.getOrDefault(signalId, Collections.emptyList());
                Map<String, Object> map = processSignalData(deviceWorkDataGroup, signalId);
                deviceDataList.add(map);
            }

        }

        return deviceDataList;
    }

    /**********************************
    * 用途说明: 绘制信号ECharts折线图
    * 参数说明 deviceWorkDataList 信号数据
    * 参数说明 signalId 信号id
    * 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
    ***********************************/
    public Map<String, Object> processSignalData(List<DeviceWorkData> deviceWorkDataList, String signalId) {
        // 生成过去60分钟的分钟时间槽
        LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
        LocalDateTime startTime = now.minusMinutes(59);
        List<LocalDateTime> minuteSlots = new ArrayList<>();
        for (int i = 0; i < 60; i++) {
            minuteSlots.add(startTime.plusMinutes(i));
        }

        // 按分钟分组数据
        Map<LocalDateTime, String> minuteDataMap = new HashMap<>();
        for (DeviceWorkData data : deviceWorkDataList) {
            LocalDateTime minuteKey = data.getStartTime().truncatedTo(ChronoUnit.MINUTES);
            minuteDataMap.put(minuteKey, data.getValue());
        }

        // 构建xAxis和series数据
        List<String> xAxisData = new ArrayList<>();
        List<Double> seriesData = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH时mm分");
        for (LocalDateTime slot : minuteSlots) {
            xAxisData.add(slot.format(formatter));
            String value = minuteDataMap.getOrDefault(slot, "0");
            if (!NumberUtil.isNumber(value)) {
                value = "0";
            }
            seriesData.add(NumberUtil.parseDouble(value));
        }

        // 构建ECharts数据结构
        Map<String, Object> result = new HashMap<>();

        Map<String, Object> xAxis = new HashMap<>();
        xAxis.put("type", "category");
        xAxis.put("data", xAxisData);
        result.put("xAxis", xAxis);

        Map<String, Object> yAxis = new HashMap<>();
        yAxis.put("type", "value");
        result.put("yAxis", yAxis);
        DeviceSignal deviceSignal = deviceSignalMapper.selectById(signalId);
        String name = deviceSignal == null ? "" : deviceSignal.getSignalName();
        List<Map<String, Object>> seriesList = new ArrayList<>();
        Map<String, Object> series = new HashMap<>();
        series.put("name", name);
        series.put("type", "line");
        series.put("data", seriesData);
        seriesList.add(series);

        // 如果需要多个系列，可以继续添加
        // 例如复制series并修改name和step

        result.put("series", seriesList);

        return result;
    }


    /**********************************
    * 用途说明: 绘制点位ECharts折线图
    * 参数说明 taskResults 点位数据
    * 参数说明 deviceId 点位id
    * 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
    ***********************************/
    public Map<String, Object> processDeviceData(List<TaskResult> taskResults, String deviceId) {
        // 定义时间格式解析器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 预处理：过滤无效数据并解析时间
        List<ProcessedData> processedList = new ArrayList<>();
        for (TaskResult result : taskResults) {
            try {
                // 解析时间字符串为LocalDateTime（仅用于排序）
                LocalDateTime dateTime = LocalDateTime.parse(result.getPatroldeviceDate(), formatter);

                // 解析数值
                double value;
                try {
                    value = NumberUtil.parseDouble(result.getValue());
                } catch (Exception e) {
                    // 非数值处理为0
                    value = 0.0;
                }

                processedList.add(new ProcessedData(
                        result.getPatroldeviceDate(),
                        value,
                        dateTime
                ));
            } catch (DateTimeParseException e) {
                // 时间解析失败时跳过此条记录
                System.err.println("Invalid date format: " + result.getPatroldeviceDate());
            }
        }

        // 按时间排序（基于解析后的LocalDateTime）
        processedList.sort(Comparator.comparing(ProcessedData::getDateTime));

        // 构建ECharts数据结构
        Map<String, Object> result = new LinkedHashMap<>();


        Map<String, Object> xAxis = new LinkedHashMap<>();
        xAxis.put("type", "category");  // 关键变化点
        xAxis.put("data", processedList.stream()
                .map(ProcessedData::getOriginalDate) // 直接使用原始字符串
                .collect(Collectors.toList()));
        result.put("xAxis", xAxis);


        Map<String, Object> yAxis = new HashMap<>();
        yAxis.put("type", "value");
        result.put("yAxis", yAxis);


        List<Double> seriesData = processedList.stream()
                .map(ProcessedData::getValue)
                .collect(Collectors.toList());

        SubstationDevice substationDevice = substationDeviceMapper.selectById(deviceId);
        String name = substationDevice == null ? "" : substationDevice.getDeviceName();
        Map<String, Object> series = new LinkedHashMap<>();
        series.put("name", name);
        series.put("type", "line");
        series.put("data", seriesData);  // 直接对应xAxis.data的顺序
        result.put("series", Collections.singletonList(series));

        return result;
    }


    private static class ProcessedData {
        // 原始时间字符串（用于最终展示）
        private final String originalDate;
        private final double value;
        // 仅用于排序
        private final LocalDateTime dateTime;

        public ProcessedData(String originalDate, double value, LocalDateTime dateTime) {
            this.originalDate = originalDate;
            this.value = value;
            this.dateTime = dateTime;
        }

        public String getOriginalDate() { return originalDate; }
        public double getValue() { return value; }
        public LocalDateTime getDateTime() { return dateTime; }
    }

}
