package com.rj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rj.entity.YhyHeartbeatLog;
import com.rj.mapper.YhyHeartbeatLogMapper;
import com.rj.service.IYhyHeartbeatLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.rj.common.TimeZoneUtils;

/**
 * <p>
 * 心跳日志表 服务实现类
 * </p>
 *
 * @author Auto Generated
 * @since 2025-01-01
 */
@Slf4j
@Service
public class YhyHeartbeatLogServiceImpl extends ServiceImpl<YhyHeartbeatLogMapper, YhyHeartbeatLog> implements IYhyHeartbeatLogService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public Map<String, Object> getHeartbeatLogList(Integer current, Integer size, String deviceNo,
                                                    String deviceStatus, Boolean powerStatus,
                                                    String heartbeatStartTime, String heartbeatEndTime,
                                                    String createStartTime, String createEndTime) {
        Map<String, Object> result = new HashMap<>();
        try {
            Page<YhyHeartbeatLog> page = new Page<>(current, size);
            LambdaQueryWrapper<YhyHeartbeatLog> queryWrapper = buildQueryWrapper(
                    deviceNo, deviceStatus, powerStatus, heartbeatStartTime, heartbeatEndTime,
                    createStartTime, createEndTime);

            Page<YhyHeartbeatLog> heartbeatLogPage = this.page(page, queryWrapper);

            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", heartbeatLogPage.getRecords());
            result.put("total", heartbeatLogPage.getTotal());
            result.put("current", heartbeatLogPage.getCurrent());
            result.put("size", heartbeatLogPage.getSize());
            result.put("pages", heartbeatLogPage.getPages());
        } catch (Exception e) {
            log.error("查询心跳日志异常", e);
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> getHeartbeatLogById(String id) {
        Map<String, Object> result = new HashMap<>();
        try {
            YhyHeartbeatLog heartbeatLog = this.getById(id);
            if (heartbeatLog != null) {
                result.put("success", true);
                result.put("message", "查询成功");
                result.put("data", heartbeatLog);
            } else {
                result.put("success", false);
                result.put("message", "心跳日志不存在");
            }
        } catch (Exception e) {
            log.error("查询心跳日志异常", e);
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> getHeartbeatLogByDeviceNo(String deviceNo) {
        Map<String, Object> result = new HashMap<>();
        try {
            LambdaQueryWrapper<YhyHeartbeatLog> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(YhyHeartbeatLog::getDeviceNo, deviceNo);
            queryWrapper.orderByDesc(YhyHeartbeatLog::getCreateTime);

            List<YhyHeartbeatLog> heartbeatLogs = this.list(queryWrapper);

            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", heartbeatLogs);
            result.put("count", heartbeatLogs.size());
        } catch (Exception e) {
            log.error("查询心跳日志异常", e);
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> addHeartbeatLog(YhyHeartbeatLog heartbeatLog) {
        Map<String, Object> result = new HashMap<>();
        try {
            LocalDateTime now = TimeZoneUtils.now();
            if (heartbeatLog.getId() == null || heartbeatLog.getId().trim().isEmpty()) {
                heartbeatLog.setId(UUID.randomUUID().toString());
            }
            heartbeatLog.setCreateTime(now);
            heartbeatLog.setUpdateTime(now);

            boolean success = this.save(heartbeatLog);
            if (success) {
                result.put("success", true);
                result.put("message", "心跳日志添加成功");
                result.put("data", heartbeatLog);
            } else {
                result.put("success", false);
                result.put("message", "心跳日志添加失败");
            }
        } catch (Exception e) {
            log.error("添加心跳日志异常", e);
            result.put("success", false);
            result.put("message", "添加异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> updateHeartbeatLog(YhyHeartbeatLog heartbeatLog) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (heartbeatLog.getId() == null || heartbeatLog.getId().trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "心跳日志ID不能为空");
                return result;
            }

            heartbeatLog.setUpdateTime(TimeZoneUtils.now());
            boolean success = this.updateById(heartbeatLog);

            if (success) {
                result.put("success", true);
                result.put("message", "心跳日志信息更新成功");
                result.put("data", heartbeatLog);
            } else {
                result.put("success", false);
                result.put("message", "心跳日志信息更新失败");
            }
        } catch (Exception e) {
            log.error("更新心跳日志异常", e);
            result.put("success", false);
            result.put("message", "更新异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> deleteHeartbeatLog(String id) {
        Map<String, Object> result = new HashMap<>();
        try {
            boolean success = this.removeById(id);
            if (success) {
                result.put("success", true);
                result.put("message", "心跳日志删除成功");
            } else {
                result.put("success", false);
                result.put("message", "心跳日志删除失败");
            }
        } catch (Exception e) {
            log.error("删除心跳日志异常", e);
            result.put("success", false);
            result.put("message", "删除异常：" + e.getMessage());
        }
        return result;
    }

    @Override
    public Map<String, Object> processHeartbeatReport(Map<String, Object> requestData) {
        Map<String, Object> result = new HashMap<>();
        try {
            YhyHeartbeatLog heartbeatLog = new YhyHeartbeatLog();
            heartbeatLog.setId(UUID.randomUUID().toString());

            // 设置数据类型（从顶层获取，如果没有则使用默认值）
            String dataType = (String) requestData.get("dataType");
            if (dataType == null || dataType.trim().isEmpty()) {
                dataType = "HeartbeatLog";
            }
            heartbeatLog.setDataType(dataType);

            // 从顶层获取时间戳
            Object timeStampObj = requestData.get("timeStamp");
            if (timeStampObj != null) {
                heartbeatLog.setTimeStamp(parseDateTime(timeStampObj));
            }

            // 提取 data 对象（大部分字段在 data 对象内）
            @SuppressWarnings("unchecked")
            Map<String, Object> dataMap = (Map<String, Object>) requestData.get("data");
            
            // 如果存在 data 对象，优先从 data 中提取字段；否则从顶层提取（保持向后兼容）
            Map<String, Object> sourceMap = dataMap != null ? dataMap : requestData;

            // 提取设备号（必需字段）- 优先从 data 中获取，如果没有则从顶层获取
            String deviceNo = null;
            if (dataMap != null && dataMap.containsKey("deviceNo")) {
                deviceNo = (String) dataMap.get("deviceNo");
            }
            if (deviceNo == null || deviceNo.trim().isEmpty()) {
                deviceNo = (String) requestData.get("deviceNo");
            }
            if (deviceNo == null || deviceNo.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "设备号不能为空");
                return result;
            }
            heartbeatLog.setDeviceNo(deviceNo);

            // 提取设备状态
            heartbeatLog.setDeviceStatus((String) sourceMap.get("deviceStatus"));

            // 提取电源状态
            Object powerStatusObj = sourceMap.get("powerStatus");
            if (powerStatusObj != null) {
                if (powerStatusObj instanceof Boolean) {
                    heartbeatLog.setPowerStatus((Boolean) powerStatusObj);
                } else if (powerStatusObj instanceof Number) {
                    heartbeatLog.setPowerStatus(((Number) powerStatusObj).intValue() == 1);
                } else if (powerStatusObj instanceof String) {
                    heartbeatLog.setPowerStatus("1".equals(powerStatusObj) || "true".equalsIgnoreCase((String) powerStatusObj));
                }
            }

            // 提取剩余电量
            Object remainPowerObj = sourceMap.get("remainPower");
            if (remainPowerObj != null) {
                if (remainPowerObj instanceof Number) {
                    heartbeatLog.setRemainPower(((Number) remainPowerObj).intValue());
                } else if (remainPowerObj instanceof String) {
                    try {
                        heartbeatLog.setRemainPower(Integer.parseInt((String) remainPowerObj));
                    } catch (NumberFormatException e) {
                        log.warn("剩余电量格式错误: {}", remainPowerObj);
                    }
                }
            }

            // 提取剩余存储空间
            Object remainStorageSizeObj = sourceMap.get("remainStorageSize");
            if (remainStorageSizeObj != null) {
                if (remainStorageSizeObj instanceof Number) {
                    heartbeatLog.setRemainStorageSize(((Number) remainStorageSizeObj).longValue());
                } else if (remainStorageSizeObj instanceof String) {
                    try {
                        heartbeatLog.setRemainStorageSize(Long.parseLong((String) remainStorageSizeObj));
                    } catch (NumberFormatException e) {
                        log.warn("剩余存储空间格式错误: {}", remainStorageSizeObj);
                    }
                }
            }

            // 提取心跳时间
            Object heartbeatTimeObj = sourceMap.get("heartbeatTime");
            if (heartbeatTimeObj != null) {
                heartbeatLog.setHeartbeatTime(parseDateTime(heartbeatTimeObj));
            }

            // 提取设备版本
            heartbeatLog.setDeviceVer((String) sourceMap.get("deviceVer"));

            // 提取扩展信息
            Object extendObj = sourceMap.get("extend");
            if (extendObj != null) {
                try {
                    heartbeatLog.setExtend(objectMapper.writeValueAsString(extendObj));
                } catch (Exception e) {
                    log.warn("序列化extend字段失败", e);
                    heartbeatLog.setExtend(extendObj.toString());
                }
            }

            // 提取主体信息
            Object bodyObj = sourceMap.get("body");
            if (bodyObj != null) {
                try {
                    heartbeatLog.setBody(objectMapper.writeValueAsString(bodyObj));
                } catch (Exception e) {
                    log.warn("序列化body字段失败", e);
                    heartbeatLog.setBody(bodyObj.toString());
                }
            }

            // 提取数据创建时间
            Object createdTimeObj = sourceMap.get("createdTime");
            if (createdTimeObj != null) {
                heartbeatLog.setCreatedTime(parseDateTime(createdTimeObj));
            }

            // 设置系统创建和更新时间
            LocalDateTime now = TimeZoneUtils.now();
            heartbeatLog.setCreateTime(now);
            heartbeatLog.setUpdateTime(now);

            // 保存到数据库
            boolean success = this.save(heartbeatLog);
            if (success) {
                result.put("success", true);
                result.put("message", "心跳日志处理成功");
                result.put("data", heartbeatLog);
                log.info("心跳日志保存成功，ID: {}, 设备号: {}, 心跳时间: {}", 
                        heartbeatLog.getId(), heartbeatLog.getDeviceNo(), heartbeatLog.getHeartbeatTime());
            } else {
                result.put("success", false);
                result.put("message", "心跳日志保存失败");
            }
        } catch (Exception e) {
            log.error("处理心跳上报数据异常", e);
            result.put("success", false);
            result.put("message", "处理异常：" + e.getMessage());
        }
        return result;
    }

    /**
     * 解析日期时间
     * 支持多种时间格式：
     * - 2025-11-30T09:27:32.3963139
     * - 2025-11-30T09:27:32.3963443+08:00
     * - 2025-11-30T01:27:32Z
     * - 2025-11-30 09:27:32
     */
    private LocalDateTime parseDateTime(Object dateTimeObj) {
        if (dateTimeObj == null) {
            return null;
        }
        if (dateTimeObj instanceof LocalDateTime) {
            return (LocalDateTime) dateTimeObj;
        }
        if (dateTimeObj instanceof String) {
            String dateTimeStr = (String) dateTimeObj;
            if (dateTimeStr.trim().isEmpty()) {
                return null;
            }
            
            try {
                // 检测是否包含时区信息：以Z结尾，或包含时区偏移格式（+HH:MM 或 -HH:MM）
                boolean hasTimezone = dateTimeStr.endsWith("Z") || 
                                     dateTimeStr.matches(".*[+-]\\d{2}:\\d{2}(?:\\d{2})?$");
                
                if (hasTimezone) {
                    // 处理ISO 8601格式，包含时区信息
                    ZonedDateTime zonedDateTime;
                    if (dateTimeStr.endsWith("Z")) {
                        // UTC时间，转换为应用配置的时区
                        zonedDateTime = ZonedDateTime.parse(dateTimeStr.replace("Z", "+00:00"))
                                .withZoneSameInstant(TimeZoneUtils.getZoneId());
                    } else {
                        // 带时区偏移的时间，转换为应用配置的时区
                        zonedDateTime = ZonedDateTime.parse(dateTimeStr)
                                .withZoneSameInstant(TimeZoneUtils.getZoneId());
                    }
                    return zonedDateTime.toLocalDateTime();
                } else {
                    // 没有时区信息，尝试多种格式解析
                    // 首先尝试标准格式：yyyy-MM-dd HH:mm:ss
                    try {
                        return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMATTER);
                    } catch (Exception e1) {
                        // 尝试ISO格式（不带时区）：2025-11-30T09:27:32.3963139
                        try {
                            // 如果有小数点，可能需要处理微秒
                            if (dateTimeStr.contains(".")) {
                                String cleanTimeStr = dateTimeStr;
                                // 移除微秒部分（如果超过6位）
                                int dotIndex = cleanTimeStr.indexOf(".");
                                if (dotIndex > 0) {
                                    String beforeDot = cleanTimeStr.substring(0, dotIndex);
                                    String afterDot = cleanTimeStr.substring(dotIndex + 1);
                                    // 如果小数点后有超过9位数字，截取前9位（纳秒精度）
                                    if (afterDot.length() > 9) {
                                        afterDot = afterDot.substring(0, 9);
                                    }
                                    // 补齐到9位（纳秒）
                                    while (afterDot.length() < 9) {
                                        afterDot += "0";
                                    }
                                    cleanTimeStr = beforeDot + "." + afterDot;
                                }
                                return LocalDateTime.parse(cleanTimeStr);
                            } else {
                                return LocalDateTime.parse(dateTimeStr);
                            }
                        } catch (Exception e2) {
                            // 最后尝试：移除T并格式化
                            try {
                                String cleanTimeStr = dateTimeStr;
                                if (cleanTimeStr.contains("T")) {
                                    cleanTimeStr = cleanTimeStr.replace("T", " ");
                                }
                                if (cleanTimeStr.contains(".")) {
                                    cleanTimeStr = cleanTimeStr.substring(0, cleanTimeStr.indexOf("."));
                                }
                                if (cleanTimeStr.length() > 19) {
                                    cleanTimeStr = cleanTimeStr.substring(0, 19);
                                }
                                return LocalDateTime.parse(cleanTimeStr, DATE_TIME_FORMATTER);
                            } catch (Exception e3) {
                                log.warn("日期时间格式错误，无法解析: {}", dateTimeStr);
                                return null;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("解析日期时间失败: {}, 错误: {}", dateTimeStr, e.getMessage());
                return null;
            }
        }
        return null;
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<YhyHeartbeatLog> buildQueryWrapper(String deviceNo, String deviceStatus,
                                                                   Boolean powerStatus, String heartbeatStartTime,
                                                                   String heartbeatEndTime, String createStartTime,
                                                                   String createEndTime) {
        LambdaQueryWrapper<YhyHeartbeatLog> queryWrapper = new LambdaQueryWrapper<>();

        // 添加设备号查询条件
        if (deviceNo != null && !deviceNo.trim().isEmpty()) {
            queryWrapper.eq(YhyHeartbeatLog::getDeviceNo, deviceNo.trim());
        }

        // 添加设备状态查询条件
        if (deviceStatus != null && !deviceStatus.trim().isEmpty()) {
            queryWrapper.eq(YhyHeartbeatLog::getDeviceStatus, deviceStatus.trim());
        }

        // 添加电源状态查询条件
        if (powerStatus != null) {
            queryWrapper.eq(YhyHeartbeatLog::getPowerStatus, powerStatus);
        }

        // 添加心跳时间范围查询条件
        if (heartbeatStartTime != null && !heartbeatStartTime.trim().isEmpty()) {
            try {
                LocalDateTime startTime = LocalDateTime.parse(heartbeatStartTime, DATE_TIME_FORMATTER);
                queryWrapper.ge(YhyHeartbeatLog::getHeartbeatTime, startTime);
            } catch (Exception e) {
                log.warn("心跳开始时间格式错误: {}", heartbeatStartTime);
            }
        }
        if (heartbeatEndTime != null && !heartbeatEndTime.trim().isEmpty()) {
            try {
                LocalDateTime endTime = LocalDateTime.parse(heartbeatEndTime, DATE_TIME_FORMATTER);
                queryWrapper.le(YhyHeartbeatLog::getHeartbeatTime, endTime);
            } catch (Exception e) {
                log.warn("心跳结束时间格式错误: {}", heartbeatEndTime);
            }
        }

        // 添加创建时间范围查询条件
        if (createStartTime != null && !createStartTime.trim().isEmpty()) {
            try {
                LocalDateTime startTime = LocalDateTime.parse(createStartTime, DATE_TIME_FORMATTER);
                queryWrapper.ge(YhyHeartbeatLog::getCreateTime, startTime);
            } catch (Exception e) {
                log.warn("创建开始时间格式错误: {}", createStartTime);
            }
        }
        if (createEndTime != null && !createEndTime.trim().isEmpty()) {
            try {
                LocalDateTime endTime = LocalDateTime.parse(createEndTime, DATE_TIME_FORMATTER);
                queryWrapper.le(YhyHeartbeatLog::getCreateTime, endTime);
            } catch (Exception e) {
                log.warn("创建结束时间格式错误: {}", createEndTime);
            }
        }

        // 按创建时间倒序排列
        queryWrapper.orderByDesc(YhyHeartbeatLog::getCreateTime);

        return queryWrapper;
    }
}
