package com.data.emqx.service.impl;

/**
 * @author licd
 * @className DeviceDataServiceImpl
 * @description 设备数据处理服务实现
 * @date 2026/03/17
 */

import com.data.emqx.domain.DeviceAlarm;
import com.data.emqx.domain.DeviceAlarmUwb;
import com.data.emqx.domain.DeviceHeart;
import com.data.emqx.domain.DeviceParamWrite;
import com.data.emqx.domain.DeviceWeightRfid;
import com.data.emqx.domain.LoadCarDataSoure;
import com.data.emqx.domain.OtaProgress;
import com.data.emqx.mapper.DeviceDataMapper;
import com.data.emqx.mapper.DeviceParamWriteMapper;
import com.data.emqx.mapper.LoadCarDataSoureMapper;
import com.data.emqx.mapper.OtaProgressMapper;
import com.data.emqx.service.IDeviceDataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;

@Service
public class DeviceDataServiceImpl implements IDeviceDataService {

    private static final Logger logger = LoggerFactory.getLogger(DeviceDataServiceImpl.class);

    @Autowired
    private DeviceDataMapper deviceDataMapper;

    @Autowired
    private LoadCarDataSoureMapper loadCarDataSoureMapper;

    @Autowired
    private OtaProgressMapper otaProgressMapper;

    @Autowired
    private DeviceParamWriteMapper deviceParamWriteMapper;

    private final SimpleDateFormat utcFormat;
    private final SimpleDateFormat timestampFormat;

    public DeviceDataServiceImpl() {
        utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        utcFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 使用东八区时区
        
        timestampFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        timestampFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 使用东八区时区
    }

    /**
     * 检查是否已存在相同的称重&标签数据
     */
    @Override
    public boolean existsWeightRfidData(String deviceId, Long seqNum) {
        try {
            int count = deviceDataMapper.countWeightRfidByDeviceIdAndSeqNum(deviceId, seqNum);
            return count > 0;
        } catch (Exception e) {
            logger.error("检查称重数据是否存在异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存称重&标签数据
     */
    @Override
    public void saveWeightRfidData(String deviceId, Long seqNum, Long sendTime, Integer weight, String rfid) {
        try {
            Date sendDate = new Date(sendTime * 1000);
            String formattedTime = utcFormat.format(sendDate);
            String timestampTime = timestampFormat.format(sendDate);

            logger.info("保存称重数据 - DeviceID: {}, SeqNum: {}, SendTime(UTC0): {}, Weight: {}kg, RFID: {}",
                    deviceId, seqNum, formattedTime, weight, rfid);

            // 创建 LoadCarDataSoure 对象用于保存数据
            LoadCarDataSoure loadCarDataSoure = new LoadCarDataSoure();
            String loadCarId = UUID.randomUUID().toString();
            loadCarDataSoure.setId(loadCarId);
            loadCarDataSoure.setDeviceId(deviceId);
            loadCarDataSoure.setDeviceStatus("OK"); // 设备状态，默认正常
            loadCarDataSoure.setSendTime(timestampTime); // 时间格式转换为 yyyyMMddHHmmssSSS 格式
            loadCarDataSoure.setWeight(weight != null ? weight.doubleValue() : 0.0);
            loadCarDataSoure.setWeightStatus(1); // 重量状态，1表示有变化
            loadCarDataSoure.setWeightTime(timestampTime); // 称重时间，使用 yyyyMMddHHmmssSSS 格式
            loadCarDataSoure.setFlag(0); // 是否已处理，0表示未处理
            loadCarDataSoure.setTag("weight"); // 标签，用于标识数据类型
            loadCarDataSoure.setCreateTime(new Date());
            loadCarDataSoure.setUpdateTime(new Date());

            // 保存到 emqx_load_car 表
            loadCarDataSoureMapper.addLoadCarDataSourceMapper(loadCarDataSoure);
            logger.info("称重数据保存到 emqx_load_car 成功 - DeviceID: {}, LoadCarID: {}", deviceId, loadCarId);

            // 处理 RFID 数据，保存到 emqx_unload_car 表
            if (rfid != null && !rfid.isEmpty()) {
                String[] rfidArray = rfid.split(",");
                LoadCarDataSoure unloadCarDataSoure = new LoadCarDataSoure();
                unloadCarDataSoure.setId(UUID.randomUUID().toString());
                unloadCarDataSoure.setDeviceId(deviceId);
                unloadCarDataSoure.setDeviceStatus("OK");
                unloadCarDataSoure.setSendTime(timestampTime); // 时间格式转换为 yyyyMMddHHmmssSSS 格式
                unloadCarDataSoure.setRfidNum(rfidArray.length);
                unloadCarDataSoure.setRfidNo(rfid);
                unloadCarDataSoure.setRfidTime(timestampTime); // RFID 时间，使用 yyyyMMddHHmmssSSS 格式
                unloadCarDataSoure.setFlag(0);
                unloadCarDataSoure.setTag("rfid");
                unloadCarDataSoure.setLoadCarId(loadCarId); // 关联 emqx_load_car 表的 ID
                unloadCarDataSoure.setCreateTime(new Date());
                unloadCarDataSoure.setUpdateTime(new Date());

                // 保存到 emqx_unload_car 表
                loadCarDataSoureMapper.addUnLoadCarDataSourceMapper(unloadCarDataSoure);
                logger.info("RFID数据保存到 emqx_unload_car 成功 - DeviceID: {}, LoadCarID: {}, RFID数量: {}", 
                        deviceId, loadCarId, rfidArray.length);
            }

            // 同时保存到原有的 emqx_device_weight_rfid 表，确保数据完整性
            DeviceWeightRfid deviceWeightRfid = new DeviceWeightRfid();
            deviceWeightRfid.setId(UUID.randomUUID().toString());
            deviceWeightRfid.setDeviceId(deviceId);
            deviceWeightRfid.setSeqNum(seqNum);
            deviceWeightRfid.setSendTime(sendTime);
            deviceWeightRfid.setWeight(weight);
            deviceWeightRfid.setRfid(rfid);
            deviceWeightRfid.setFlag(0);
            deviceWeightRfid.setCreateTime(new Date());
            deviceWeightRfid.setUpdateTime(new Date());

            deviceDataMapper.insertWeightRfid(deviceWeightRfid);
            logger.info("称重数据保存到 emqx_device_weight_rfid 成功 - DeviceID: {}, SeqNum: {}", deviceId, seqNum);

        } catch (Exception e) {
            logger.error("保存称重数据异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 检查是否已存在相同的告警数据
     */
    @Override
    public boolean existsAlarmData(String deviceId, Long seqNum) {
        try {
            int count = deviceDataMapper.countAlarmByDeviceIdAndSeqNum(deviceId, seqNum);
            return count > 0;
        } catch (Exception e) {
            logger.error("检查告警数据是否存在异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查是否已存在相同的心跳数据
     */
    @Override
    public boolean existsHeartData(String deviceId, Long sendTime) {
        try {
            int count = deviceDataMapper.countHeartByDeviceIdAndSendTime(deviceId, sendTime);
            return count > 0;
        } catch (Exception e) {
            logger.error("检查心跳数据是否存在异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存告警数据
     */
    @Override
    public void saveAlarmData(String deviceId, Long seqNum, Long sendTime, String uwb, com.alibaba.fastjson.JSONArray uwbArray) {
        try {
            Date sendDate = new Date(sendTime * 1000);
            String formattedTime = utcFormat.format(sendDate);

            logger.info("保存告警数据 - DeviceID: {}, SeqNum: {}, SendTime(UTC0): {}, UWB: {}",
                    deviceId, seqNum, formattedTime, uwb);

            // 创建对象并设置值
            DeviceAlarm deviceAlarm = new DeviceAlarm();
            String alarmId = UUID.randomUUID().toString();
            deviceAlarm.setId(alarmId);
            deviceAlarm.setDeviceId(deviceId);
            deviceAlarm.setSeqNum(seqNum);
            deviceAlarm.setSendTime(sendTime);
            deviceAlarm.setUwb(uwb);
            deviceAlarm.setFlag(0);
            deviceAlarm.setCreateTime(new Date());
            deviceAlarm.setUpdateTime(new Date());

            // 保存到数据库
            deviceDataMapper.insertAlarm(deviceAlarm);
            logger.info("告警数据保存成功 - DeviceID: {}, SeqNum: {}", deviceId, seqNum);

            // 保存UWB数据到关联表
            if (uwbArray != null && !uwbArray.isEmpty()) {
                for (int i = 0; i < uwbArray.size(); i++) {
                    com.alibaba.fastjson.JSONObject uwbObj = uwbArray.getJSONObject(i);
                    if (uwbObj != null) {
                        String id = uwbObj.getString("ID");
                        String dist = uwbObj.getString("Dist");

                        if (id != null && dist != null) {
                            DeviceAlarmUwb deviceAlarmUwb = new DeviceAlarmUwb();
                            deviceAlarmUwb.setId(UUID.randomUUID().toString());
                            deviceAlarmUwb.setAlarmId(alarmId);
                            deviceAlarmUwb.setUwbId(id);
                            deviceAlarmUwb.setDist(dist);
                            deviceAlarmUwb.setCreateTime(new Date());
                            deviceAlarmUwb.setUpdateTime(new Date());

                            deviceDataMapper.insertAlarmUwb(deviceAlarmUwb);
                            logger.info("UWB数据保存成功 - AlarmID: {}, UWB ID: {}, Dist: {}", alarmId, id, dist);
                        }
                    }
                }
            }

        } catch (Exception e) {
            logger.error("保存告警数据异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 保存心跳数据
     */
    @Override
    public void saveHeartData(String deviceId, Double sysVol, Integer netRSSI, Long sendTime) {
        try {
            Date sendDate = new Date(sendTime * 1000);
            String formattedTime = utcFormat.format(sendDate);

            logger.info("保存心跳数据 - DeviceID: {}, sysVol: {}, netRSSI: {}, SendTime(UTC0): {}",
                    deviceId, sysVol, netRSSI, formattedTime);

            // 创建对象并设置值
            DeviceHeart deviceHeart = new DeviceHeart();
            deviceHeart.setId(UUID.randomUUID().toString());
            deviceHeart.setDeviceId(deviceId);
            deviceHeart.setSysVol(sysVol);
            deviceHeart.setNetRSSI(netRSSI);
            deviceHeart.setSendTime(sendTime);
            deviceHeart.setFlag(0);
            deviceHeart.setCreateTime(new Date());
            deviceHeart.setUpdateTime(new Date());

            // 保存到数据库
            deviceDataMapper.insertHeart(deviceHeart);
            logger.info("心跳数据保存成功 - DeviceID: {}", deviceId);

        } catch (Exception e) {
            logger.error("保存心跳数据异常: {}", e.getMessage(), e);
        }
    }

    /**
     * V2.0.1 保存OTA升级进度数据
     */
    @Override
    public void saveOtaProgressData(String deviceId, String taskID, Integer progress, String status) {
        try {
            logger.info("保存OTA升级进度数据 - DeviceID: {}, TaskID: {}, Progress: {}%, Status: {}",
                    deviceId, taskID, progress, status);

            // 查询是否已存在该任务记录
            OtaProgress existingProgress = otaProgressMapper.selectByDeviceIdAndTaskId(deviceId, taskID);

            if (existingProgress != null) {
                // 更新现有记录
                existingProgress.setProgress(progress);
                existingProgress.setStatus(status);
                existingProgress.setUpdateTime(new Date());
                otaProgressMapper.updateProgressByDeviceIdAndTaskId(existingProgress);
                logger.info("OTA升级进度数据更新成功 - DeviceID: {}, TaskID: {}", deviceId, taskID);
            } else {
                // 创建新记录
                OtaProgress otaProgress = new OtaProgress();
                otaProgress.setId(UUID.randomUUID().toString());
                otaProgress.setDeviceId(deviceId);
                otaProgress.setTaskId(taskID);
                otaProgress.setProgress(progress);
                otaProgress.setStatus(status);
                otaProgress.setCreateTime(new Date());
                otaProgress.setUpdateTime(new Date());
                otaProgressMapper.insertOtaProgress(otaProgress);
                logger.info("OTA升级进度数据保存成功 - DeviceID: {}, TaskID: {}", deviceId, taskID);
            }

        } catch (Exception e) {
            logger.error("保存OTA升级进度数据异常: {}", e.getMessage(), e);
        }
    }

    /**
     * V2.0.1 保存设备参数读取响应数据
     */
    @Override
    public void saveParamReadData(String deviceId, Long seqNum, com.alibaba.fastjson.JSONObject params) {
        try {
            logger.info("保存设备参数读取响应 - DeviceID: {}, SeqNum: {}, Params: {}",
                    deviceId, seqNum, params != null ? params.toJSONString() : "null");

            // 解析并记录各参数
            if (params != null) {
                Integer rs485PollMs = params.getInteger("Rs485_PollMs");
                Integer uwbAlarmMs = params.getInteger("UWB_AlarmMs");
                Integer voiceAlarmMs = params.getInteger("VoiceAlarmMs");
                Integer uwbIgnoreCm = params.getInteger("UWB_IgnoreCm");
                Integer uwbAlarmCm = params.getInteger("UWB_AlarmCm");
                String iccid = params.getString("ICCID");

                logger.info("设备参数详情 - Rs485_PollMs: {}, UWB_AlarmMs: {}, VoiceAlarmMs: {}, UWB_IgnoreCm: {}, UWB_AlarmCm: {}, ICCID: {}",
                        rs485PollMs, uwbAlarmMs, voiceAlarmMs, uwbIgnoreCm, uwbAlarmCm, iccid);
            }

            // TODO: 需要创建 emqx_device_param_read 表和对应的 Domain/Mapper
            // 目前仅记录日志，后续需要实现数据库保存逻辑

            logger.info("设备参数读取响应保存成功 - DeviceID: {}, SeqNum: {}", deviceId, seqNum);

        } catch (Exception e) {
            logger.error("保存设备参数读取响应异常: {}", e.getMessage(), e);
        }
    }

    /**
     * V2.0.1 保存设备参数写入响应数据
     * 更新参数写入状态，用于实现"设备期望值"功能
     */
    @Override
    public void saveParamWriteData(String deviceId, Long seqNum, String status, String failReason) {
        try {
            logger.info("保存设备参数写入响应 - DeviceID: {}, SeqNum: {}, Status: {}, FailReason: {}",
                    deviceId, seqNum, status, failReason);

            // 创建更新对象
            DeviceParamWrite paramWrite = new DeviceParamWrite();
            paramWrite.setDeviceId(deviceId);
            paramWrite.setSeqNum(seqNum);
            paramWrite.setStatus(status);
            paramWrite.setFailReason(failReason);
            paramWrite.setUpdateTime(new Date());

            // 更新状态（这里简化处理，实际应该根据具体参数名更新）
            // 在实际场景中，设备会返回具体哪个参数写入成功/失败
            // 这里需要根据业务需求进一步完善

            logger.info("设备参数写入响应保存成功 - DeviceID: {}, SeqNum: {}, Status: {}", deviceId, seqNum, status);

        } catch (Exception e) {
            logger.error("保存设备参数写入响应异常: {}", e.getMessage(), e);
        }
    }

    /**
     * V2.0.1 保存设备参数期望值（用于设备上线后自动拉平配置）
     */
    public void saveParamExpectation(String deviceId, String paramKey, String paramValue) {
        try {
            logger.info("保存设备参数期望值 - DeviceID: {}, ParamKey: {}, ParamValue: {}",
                    deviceId, paramKey, paramValue);

            // 查询是否已存在该参数记录
            DeviceParamWrite existingParam = deviceParamWriteMapper.selectByDeviceIdAndParamKey(deviceId, paramKey);

            if (existingParam != null) {
                // 更新现有记录的期望值
                existingParam.setParamValue(paramValue);
                existingParam.setStatus("Pending");
                existingParam.setFailReason(null);
                existingParam.setUpdateTime(new Date());
                deviceParamWriteMapper.updateStatusByDeviceIdAndParamKey(existingParam);
                logger.info("设备参数期望值更新成功 - DeviceID: {}, ParamKey: {}", deviceId, paramKey);
            } else {
                // 创建新记录
                DeviceParamWrite paramWrite = new DeviceParamWrite();
                paramWrite.setId(UUID.randomUUID().toString());
                paramWrite.setDeviceId(deviceId);
                paramWrite.setParamKey(paramKey);
                paramWrite.setParamValue(paramValue);
                paramWrite.setStatus("Pending");
                paramWrite.setCreateTime(new Date());
                paramWrite.setUpdateTime(new Date());
                deviceParamWriteMapper.insertParamWrite(paramWrite);
                logger.info("设备参数期望值保存成功 - DeviceID: {}, ParamKey: {}", deviceId, paramKey);
            }

        } catch (Exception e) {
            logger.error("保存设备参数期望值异常: {}", e.getMessage(), e);
        }
    }
}
