package cn.iocoder.yudao.module.iot.service.devicewarinningrecord;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.iot.controller.admin.devicewarinningrecord.vo.*;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicewarinningrecord.DeviceWarinningRecordDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.iot.dal.mysql.devicewarinningrecord.DeviceWarinningRecordMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;

/**
 * 告警记录 Service 实现类
 *
 * @author 必硕科技
 */
@Service
@Validated
public class DeviceWarinningRecordServiceImpl implements DeviceWarinningRecordService {

    @Resource
    private DeviceWarinningRecordMapper deviceWarinningRecordMapper;

    @Override
    public Long createDeviceWarinningRecord(DeviceWarinningRecordSaveReqVO createReqVO) {
        // 插入
        DeviceWarinningRecordDO deviceWarinningRecord = BeanUtils.toBean(createReqVO, DeviceWarinningRecordDO.class);
        deviceWarinningRecordMapper.insert(deviceWarinningRecord);
        // 返回
        return deviceWarinningRecord.getId();
    }

    @Override
    public void updateDeviceWarinningRecord(DeviceWarinningRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateDeviceWarinningRecordExists(updateReqVO.getId());
        // 更新
        DeviceWarinningRecordDO updateObj = BeanUtils.toBean(updateReqVO, DeviceWarinningRecordDO.class);
        deviceWarinningRecordMapper.updateById(updateObj);
    }

    @Override
    public void deleteDeviceWarinningRecord(Long id) {
        // 校验存在
        validateDeviceWarinningRecordExists(id);
        // 删除
        deviceWarinningRecordMapper.deleteById(id);
    }

    private void validateDeviceWarinningRecordExists(Long id) {
        if (deviceWarinningRecordMapper.selectById(id) == null) {
            throw exception(DEVICE_WARINNING_RECORD_NOT_EXISTS);
        }
    }

    @Override
    public DeviceWarinningRecordDO getDeviceWarinningRecord(Long id) {
        return deviceWarinningRecordMapper.selectById(id);
    }

    @Override
    public PageResult<DeviceWarinningRecordDO> getDeviceWarinningRecordPage(DeviceWarinningRecordPageReqVO pageReqVO) {
        return deviceWarinningRecordMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DeviceWarinningRecordDO> getList(Long id) {
        return deviceWarinningRecordMapper.selectList(Wrappers.<DeviceWarinningRecordDO>lambdaQuery()
                .eq(id != null, DeviceWarinningRecordDO::getDeviceId, id));
    }

    @Override
    public List<Map<String, Object>> getLastSevenHoursCount() {

        // 查询近七个小时数据
        List<Map<String, Object>> result = deviceWarinningRecordMapper.getLastSevenHoursCount();

        // 补全最近7个小时的所有时间段（即使没有告警也显示0）
        return fillMissingHours(result);


    }


    /**
     * 补全最近7个小时的所有时间段
     */
    private List<Map<String, Object>> fillMissingHours(List<Map<String, Object>> dbResult) {
        // 创建结果列表
        List<Map<String, Object>> result = new ArrayList<>();

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00");

        // 将数据库查询结果转换为以hour为key的Map
        Map<String, Long> countMap = dbResult.stream()
                .collect(Collectors.toMap(
                        map -> (String) map.get("hour"),
                        map -> (Long) map.get("count")
                ));

        // 生成最近7个小时的时间段
        for (int i = 6; i >= 0; i--) {
            LocalDateTime hourTime = now.minusHours(i);
            String hourStr = hourTime.format(formatter);

            Map<String, Object> hourData = new HashMap<>();
            hourData.put("hour", hourStr);
            hourData.put("count", countMap.getOrDefault(hourStr, 0L));
//            hourData.put("hourTime", hourTime.toString());

            result.add(hourData);
        }

        return result;
    }
}