package com.agri.system.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import com.agri.common.utils.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.agri.system.mapper.SysDevOperLogMapper;
import com.agri.system.domain.SysDevOperLog;
import com.agri.system.service.ISysDevOperLogService;

/**
 * 设备控制操作日志Service业务层处理
 * 
 * @author lld
 * @date 2026-01-29
 */
@Service
public class SysDevOperLogServiceImpl extends ServiceImpl<SysDevOperLogMapper, SysDevOperLog> implements ISysDevOperLogService 
{

    /**
     * 查询设备控制操作日志
     * 
     * @param id 设备控制操作日志主键
     * @return 设备控制操作日志
     */
    @Override
    public SysDevOperLog selectSysDevOperLogById(Long id)
    {
        return baseMapper.selectSysDevOperLogById(id);
    }

    /**
     * 查询设备控制操作日志列表
     * 
     * @param sysDevOperLog 设备控制操作日志
     * @return 设备控制操作日志
     */
    @Override
    public List<SysDevOperLog> selectSysDevOperLogList(SysDevOperLog sysDevOperLog)
    {
        return baseMapper.selectSysDevOperLogList(sysDevOperLog);
    }

    /**
     * 新增设备控制操作日志
     * 
     * @param sysDevOperLog 设备控制操作日志
     * @return 结果
     */
    @Override
    public int insertSysDevOperLog(SysDevOperLog sysDevOperLog)
    {
        sysDevOperLog.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertSysDevOperLog(sysDevOperLog);
    }

    /**
     * 修改设备控制操作日志
     * 
     * @param sysDevOperLog 设备控制操作日志
     * @return 结果
     */
    @Override
    public int updateSysDevOperLog(SysDevOperLog sysDevOperLog)
    {
        sysDevOperLog.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateSysDevOperLog(sysDevOperLog);
    }

    /**
     * 批量删除设备控制操作日志
     * 
     * @param ids 需要删除的设备控制操作日志主键
     * @return 结果
     */
    @Override
    public int deleteSysDevOperLogByIds(Long[] ids)
    {
        return baseMapper.deleteSysDevOperLogByIds(ids);
    }

    /**
     * 删除设备控制操作日志信息
     * 
     * @param id 设备控制操作日志主键
     * @return 结果
     */
    @Override
    public int deleteSysDevOperLogById(Long id)
    {
        return baseMapper.deleteSysDevOperLogById(id);
    }


    /**
     * 固定IMEI列表 → 链式lambdaQuery查询 → 内存分组取每个IMEI第一条
     * 核心：用 super.lambdaQuery() 替代手动new LambdaQueryWrapper
     */
    /**
     * 固定IMEI列表 → 链式查询 → 嵌套Map返回【每个IMEI→每个roller→今日日志条数】
     * 性能最优：仅统计数量，无完整对象开销
     */
    /**
     * 极致性能版：SQL层面直接统计【每个IMEI→每个func_code→今日日志条数】
     * 适配表结构：利用idx_imei_time/idx_func索引，规避大JSON字段开销
     */
    public Map<String, Map<String, Integer>> getTodayLogCountByImeiMap(List<String> imeiList) {
        // 1. 构造今日时间范围（精准过滤，避免毫秒级漏查）
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime tomorrowStart = LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.MIN);

        // 2. 构建SQL层面的分组统计查询（仅查必要字段，利用索引）
        QueryWrapper<SysDevOperLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("imei", "func_code", "COUNT(*) as count") // 仅统计必需字段
                .in("imei", imeiList) // 过滤固定IMEI列表（命中idx_imei_time/idx_func的imei前缀）
                .ge("create_time", todayStart) // 今日0点后（命中idx_imei_time的create_time）
                .lt("create_time", tomorrowStart) // 明日0点前（避免23:59:59.999漏查）
                .eq("op_type", 1)
                .notIn("func_code","jbk1","jbg1")
                .groupBy("imei", "func_code"); // 按IMEI+func_code分组（利用idx_func索引）

        // 3. 执行查询（返回Map列表，仅包含imei/func_code/count三个字段）
        List<Map<String, Object>> sqlResult = baseMapper.selectMaps(queryWrapper);

        // 4. 组装嵌套Map：Map<IMEI, Map<func_code, 今日条数>>
        Map<String, Map<String, Integer>> nestedCountMap = new HashMap<>(imeiList.size());

        // 4.1 初始化所有固定IMEI的内层Map（避免取值时NPE）
        for (String imei : imeiList) {
            nestedCountMap.put(imei, new HashMap<>());
        }
        // 4.2 填充统计结果
        for (Map<String, Object> row : sqlResult) {
            String imei = (String) row.get("imei");
            String funcCode = (String) row.get("func_code");
            Integer count = ((Number) row.get("count")).intValue();
            nestedCountMap.get(imei).put(funcCode, count);
        }
        return nestedCountMap;
    }
}
