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

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.base.gas.domain.GasMonitorData;
import com.zksy.base.gas.mapper.GasMonitorDataMapper;
import com.zksy.base.gas.service.GasMonitorDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
* @author Administrator
* @description 针对表【gas_monitor_data(可燃气体监测仪数据表)】的数据库操作Service实现
* @createDate 2025-09-19 14:51:16
*/
@Service
public class GasMonitorDataServiceImpl extends ServiceImpl<GasMonitorDataMapper, GasMonitorData>
    implements GasMonitorDataService {
    @Autowired
    private GasMonitorDataMapper gasMonitorDataMapper;
    @Override
    public GasMonitorData getLatestByDeviceId(String deviceId) {
        return lambdaQuery()
                .eq(GasMonitorData::getMacAddress, deviceId) // 用 macAddress 或者设备ID字段
                .orderByDesc(GasMonitorData::getCreateTime)
                .last("limit 1")
                .one();
    }

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

        List<Double> values = lambdaQuery()
                .select(GasMonitorData::getGasConcentration)
                .eq(GasMonitorData::getMacAddress, deviceId)
                .between(GasMonitorData::getCreateTime, start, end)
                .list()
                .stream()
                .map(v -> v.getGasConcentration() == null ? 0 : v.getGasConcentration().doubleValue())
                .collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        if (!values.isEmpty()) {
            result.put("avg", values.stream().mapToDouble(Double::doubleValue).average().orElse(0));
            result.put("max", Collections.max(values));
            result.put("min", Collections.min(values));
        } else {
            result.put("avg", 0);
            result.put("max", 0);
            result.put("min", 0);
        }
        return result;
    }

    @Override
    public double getOnlineRate(String deviceId, LocalDate start, LocalDate end) {
        LocalDateTime startTime = start.atStartOfDay();
        LocalDateTime endTime = end.plusDays(1).atStartOfDay();

        long totalDays = ChronoUnit.DAYS.between(start, end) + 1;
        if (totalDays <= 0) {
            return 0d;
        }

        long onlineDays = gasMonitorDataMapper.countDistinctOnlineDays(deviceId, startTime, endTime);
        return (double) onlineDays / (double) totalDays;
    }

    @Override
    public List<GasMonitorData> getAlarms(String deviceId, LocalDateTime start, LocalDateTime end, double threshold) {
        return lambdaQuery()
                .eq(GasMonitorData::getMacAddress, deviceId)
                .between(GasMonitorData::getCreateTime, start, end)
                .gt(GasMonitorData::getGasConcentration, threshold)
                .list();
    }

    @Override
    public List<Map<String, Object>> getTrend(String deviceId, LocalDateTime start, LocalDateTime end) {
        return lambdaQuery()
                .eq(GasMonitorData::getMacAddress, deviceId)
                .between(GasMonitorData::getCreateTime, start, end)
                .orderByAsc(GasMonitorData::getCreateTime)
                .list()
                .stream()
                .map(data -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("time", data.getCreateTime());
                    map.put("value", data.getGasConcentration());
                    return map;
                })
                .collect(Collectors.toList());
    }
    @Override
    public GasMonitorData getLatestWithAlarmBits(String deviceId) {
        GasMonitorData data = lambdaQuery()
                .eq(GasMonitorData::getMacAddress, deviceId)
                .orderByDesc(GasMonitorData::getCreateTime)
                .last("limit 1")
                .one();
        // 若数据存在，调用parseAlarmBits解析报警位
        if (data != null) {
            data.parseAlarmBits();
        }
        return data;
    }

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




