package cn.iocoder.yudao.module.pms.service.iotdevicerunlog;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicerunlog.IotDeviceRunLogDO;

import javax.validation.Valid;
import java.util.*;

/**
 * 设备运行数据记录 中间表 Service 接口
 *
 * @author ruiqi
 */
public interface IotDeviceRunLogService {

    /**
     * 创建设备运行数据记录 中间表
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    Long createIotDeviceRunLog(@Valid IotDeviceRunLogSaveReqVO createReqVO);

    /**
     * 更新设备运行数据记录 中间表
     *
     * @param updateReqVO 更新信息
     */
    void updateIotDeviceRunLog(@Valid IotDeviceRunLogSaveReqVO updateReqVO);

    /**
     * 删除设备运行数据记录 中间表
     *
     * @param id 编号
     */
    void deleteIotDeviceRunLog(Long id);

    /**
     * 获得设备运行数据记录 中间表
     *
     * @param id 编号
     * @return 设备运行数据记录 中间表
     */
    IotDeviceRunLogDO getIotDeviceRunLog(Long id);

    /**
     * 获得设备运行数据记录 中间表分页
     *
     * @param pageReqVO 分页查询
     * @return 设备运行数据记录 中间表分页
     */
    PageResult<IotDeviceRunLogDO> getIotDeviceRunLogPage(IotDeviceRunLogPageReqVO pageReqVO);

    /**
     * 设备的运行记录信息
     *
     * @return 设备运行数据记录
     */
    List<IotDeviceRunLogRespVO> distinctDevices(List<Long> ids, List<Long> deviceCategoryIds, Map<Long, Long> deviceCategoryPair, String actualStartTime);

    /**
     * 设备的运行记录信息 保养查询使用
     *
     * @return 设备运行数据记录
     */
    List<IotDeviceRunLogRespVO> distinctDevicesSearch(List<Long> ids, List<Long> deviceCategoryIds, Map<Long, Long> deviceCategoryPair, List<IotDeviceRunLogRespVO> runLogs);

    /**
     * 查询指定设备 运行记录模板属性对应的累计时长 累计里程
     * @param deviceIds
     * @return
     */
    List<IotDeviceRunLogRespVO> multipleAccumulatedData(Collection<Long> deviceIds, Collection<String> attrNames, String actualStartTime);

    /**
     * 查询指定设备 运行记录模板属性对应的累计时长 累计里程 保养查询使用
     * @param deviceIds
     * @return
     */
    List<IotDeviceRunLogRespVO> deviceAttrRunLogsSearch(List<Long> deviceIds);

    /**
     * 根据设备id查询设备关联信息
     *
     * @param ids 设备id集合
     * @return 设备bom 关联 列表
     */
    default Map<Long, IotDeviceRunLogRespVO> getDeviceRunLogMap(List<Long> ids){
        List<IotDeviceRunLogRespVO> list = distinctDevices(ids, null, null, null);
        // 删除集合中的NULL元素
        list.removeIf(deviceLog -> isAllFieldsNull(deviceLog));
        // 暂时将查询出的2条记录设置为1条
        // device_id	total_run_time	total_mileage	point_name				point_code
        // 136			2444.00			0.00			台上发动机累计运转时长	    sc
        // 136			0.00			16510.00		底盘发动机累计公里数	    gls
        // 按 deviceId 分组并合并数据
        Map<Long, IotDeviceRunLogRespVO> mergedMap = new HashMap<>();
        for (IotDeviceRunLogRespVO log : list) {
            Long deviceId = log.getDeviceId();
            // 跳过无效设备ID
            if (deviceId == null) continue;

            if (mergedMap.containsKey(deviceId)) {
                // 合并已有记录
                IotDeviceRunLogRespVO existing = mergedMap.get(deviceId);
                mergeLogRecords(existing, log);
            } else {
                // 首次遇到该设备ID，直接放入Map
                mergedMap.put(deviceId, log);
            }
        }
        List<IotDeviceRunLogRespVO> mergedList = new ArrayList<>(mergedMap.values());
        return CollectionUtils.convertMap(mergedList, IotDeviceRunLogRespVO::getDeviceId);
    }

    /**
     * 根据设备id查询设备关联信息
     *
     * @param ids 设备id集合
     * @return 设备bom 关联 列表
     */
    default Map<Long, IotDeviceRunLogRespVO> getDeviceRunLogMapAlone(List<Long> ids, List<Long> deviceCategoryIds,
                                                                     Map<Long, Long> deviceCategoryPair, String actualStartTime) {
        List<IotDeviceRunLogRespVO> list = distinctDevices(ids, deviceCategoryIds, deviceCategoryPair, actualStartTime);
        // 删除集合中的NULL元素
        list.removeIf(deviceLog -> isAllFieldsNull(deviceLog));
        // 暂时将查询出的2条记录设置为1条
        // device_id	total_run_time	total_mileage	point_name				point_code
        // 136			2444.00			0.00			台上发动机累计运转时长	    sc
        // 136			0.00			16510.00		底盘发动机累计公里数	    gls
        // 按 deviceId 分组并合并数据
        Map<Long, IotDeviceRunLogRespVO> mergedMap = new HashMap<>();
        for (IotDeviceRunLogRespVO log : list) {
            Long deviceId = log.getDeviceId();
            // 跳过无效设备ID
            if (deviceId == null) continue;

            if (mergedMap.containsKey(deviceId)) {
                // 合并已有记录
                IotDeviceRunLogRespVO existing = mergedMap.get(deviceId);
                mergeLogRecords(existing, log);
            } else {
                // 首次遇到该设备ID，直接放入Map
                mergedMap.put(deviceId, log);
            }
        }
        List<IotDeviceRunLogRespVO> mergedList = new ArrayList<>(mergedMap.values());
        return CollectionUtils.convertMap(mergedList, IotDeviceRunLogRespVO::getDeviceId);
    }

    /**
     * 根据设备id查询设备关联信息
     *
     * @param ids 设备id集合
     * @return 设备bom 关联 列表
     */
    default Map<Long, IotDeviceRunLogRespVO> getDeviceRunLogMapSearch(List<Long> ids, List<Long> deviceCategoryIds,
                                                                     Map<Long, Long> deviceCategoryPair, List<IotDeviceRunLogRespVO> runLogs) {
        List<IotDeviceRunLogRespVO> list = distinctDevicesSearch(ids, deviceCategoryIds, deviceCategoryPair, runLogs);
        // 删除集合中的NULL元素
        list.removeIf(deviceLog -> isAllFieldsNull(deviceLog));
        // 暂时将查询出的2条记录设置为1条
        // device_id	total_run_time	total_mileage	point_name				point_code
        // 136			2444.00			0.00			台上发动机累计运转时长	    sc
        // 136			0.00			16510.00		底盘发动机累计公里数	    gls
        // 按 deviceId 分组并合并数据
        Map<Long, IotDeviceRunLogRespVO> mergedMap = new HashMap<>();
        for (IotDeviceRunLogRespVO log : list) {
            Long deviceId = log.getDeviceId();
            // 跳过无效设备ID
            if (deviceId == null) continue;

            if (mergedMap.containsKey(deviceId)) {
                // 合并已有记录
                IotDeviceRunLogRespVO existing = mergedMap.get(deviceId);
                mergeLogRecords(existing, log);
            } else {
                // 首次遇到该设备ID，直接放入Map
                mergedMap.put(deviceId, log);
            }
        }
        List<IotDeviceRunLogRespVO> mergedList = new ArrayList<>(mergedMap.values());
        return CollectionUtils.convertMap(mergedList, IotDeviceRunLogRespVO::getDeviceId);
    }

    // 检查是否所有字段都为NULL的辅助方法
    default boolean isAllFieldsNull(IotDeviceRunLogRespVO deviceLog) {
        return ObjectUtil.isEmpty(deviceLog.getDeviceId());
    }

    default void mergeLogRecords(IotDeviceRunLogRespVO target, IotDeviceRunLogRespVO source) {
        // 累加数值字段（假设类型为BigDecimal）
        if (target.getTotalRunTime() != null && source.getTotalRunTime() != null) {
            target.setTotalRunTime(target.getTotalRunTime().add(source.getTotalRunTime()));
        } else if (source.getTotalRunTime() != null) {
            target.setTotalRunTime(source.getTotalRunTime());
        }

        if (target.getTotalMileage() != null && source.getTotalMileage() != null) {
            target.setTotalMileage(target.getTotalMileage().add(source.getTotalMileage()));
        } else if (source.getTotalMileage() != null) {
            target.setTotalMileage(source.getTotalMileage());
        }
        // 非数值字段保持target的原始值（即第一条记录的值）
        // 不需要额外操作
    }
}