package com.zksy.base.environment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.base.environment.domain.ERealTimeData;
import com.zksy.base.environment.mapper.ERealTimeDataMapper;
import com.zksy.base.environment.service.ERealTimeDataService;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【e_real_time_data(环境实时数据)】的数据库操作Service实现
* @createDate 2025-08-27 10:30:48
*/
@Service
public class ERealTimeDataServiceImpl extends ServiceImpl<ERealTimeDataMapper, ERealTimeData>
        implements ERealTimeDataService {

    @Override
    public ERealTimeData getLatestByDeviceNode(Integer deviceId, Integer nodeId) {
        return lambdaQuery()
                .eq(ERealTimeData::getDeviceId, deviceId)
                .eq(ERealTimeData::getNodeId, nodeId)
                .orderByDesc(ERealTimeData::getCreateTime)
                .last("limit 1")
                .one();
    }

    @Override
    public Map<String, Object> getDailyStats(Integer deviceId, Integer nodeId, LocalDate date) {
        LocalDateTime start = date.atStartOfDay();
        LocalDateTime end = start.plusDays(1);

        List<ERealTimeData> list = lambdaQuery()
                .eq(ERealTimeData::getDeviceId, deviceId)
                .eq(ERealTimeData::getNodeId, nodeId)
                .between(ERealTimeData::getCreateTime, start, end)
                .list();

        Map<String, Object> result = new HashMap<>();
        if (list.isEmpty()) {
            result.put("avgValue", 0);
            result.put("maxValue", 0);
            result.put("minValue", 0);
            result.put("records", Collections.emptyList());
            return result;
        }

        List<Double> valueList = list.stream().map(this::getNodeValue).collect(Collectors.toList());

        result.put("avgValue", valueList.stream().mapToDouble(Double::doubleValue).average().orElse(0));
        result.put("maxValue", valueList.stream().mapToDouble(Double::doubleValue).max().orElse(0));
        result.put("minValue", valueList.stream().mapToDouble(Double::doubleValue).min().orElse(0));

        List<Map<String, Object>> records = list.stream().map(d -> {
            Map<String, Object> map = new HashMap<>();
            map.put("time", d.getCreateTime());
            map.put("value", getNodeValue(d));
            return map;
        }).collect(Collectors.toList());
        result.put("records", records);

        return result;
    }

    @Override
    public List<Map<String, Object>> getTrend(Integer deviceId, Integer nodeId, LocalDateTime start, LocalDateTime end) {
        return lambdaQuery()
                .eq(ERealTimeData::getDeviceId, deviceId)
                .eq(ERealTimeData::getNodeId, nodeId)
                .between(ERealTimeData::getCreateTime, start, end)
                .orderByAsc(ERealTimeData::getCreateTime)
                .list()
                .stream()
                .map(d -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("time", d.getCreateTime());
                    map.put("value", getNodeValue(d));
                    return map;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getAlarms(Integer deviceId, Integer nodeId, LocalDateTime start, LocalDateTime end,
                                               Double threshold) {
        List<ERealTimeData> list = lambdaQuery()
                .eq(ERealTimeData::getDeviceId, deviceId)
                .eq(ERealTimeData::getNodeId, nodeId)
                .between(ERealTimeData::getCreateTime, start, end)
                .list();

        if (threshold != null) {
            list = list.stream().filter(d -> getNodeValue(d) > threshold).collect(Collectors.toList());
        }

        return list.stream().map(d -> {
            Map<String, Object> map = new HashMap<>();
            map.put("time", d.getCreateTime());
            map.put("value", getNodeValue(d));
            return map;
        }).collect(Collectors.toList());
    }

    // 工具方法：根据节点类型获取实际值
    private Double getNodeValue(ERealTimeData data) {
        if (data.getNodeId() == null) return 0d;

        switch (data.getNodeId()) {
            case 1: // 悬浮物
                try {
                    return data.getFloatValue() == null ? 0d : Double.parseDouble(data.getFloatValue());
                } catch (NumberFormatException e) {
                    return 0d;
                }
            case 2: // COD
            case 3: // 氨氮
            case 4: // 电导率
            case 5: // PH
                return data.getHum() == null ? 0d : data.getHum().doubleValue();
            default:
                return 0d;
        }
    }

    @Override
    public List<String> getDeviceGroup() {
        return lambdaQuery()
                .select(ERealTimeData::getDeviceId)
                .groupBy(ERealTimeData::getDeviceId)
                .list()
                .stream()
                .map(ERealTimeData::getDeviceId)
                .map(String::valueOf)
                .collect(Collectors.toList());
    }
}




