package org.dromara.app.handler;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.app.domain.bo.AppDeviceBo;
import org.dromara.app.mqtt.MqttTopicHandler;
import org.dromara.app.service.IAppDeviceService;
import org.dromara.common.json.utils.JsonUtils;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 设备电量及在线心跳处理器，匹配 /{deviceNo}/publish/power。
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceDataHandler implements MqttTopicHandler {

    private static final Pattern PATTERN = Pattern.compile("^/([^/]+)/publish/power$");
    private final IAppDeviceService appDeviceService;
    private final DeviceIdentityResolver deviceIdentityResolver;
    private final MqttDeviceStatusService deviceStatusService;

    @Override
    public Pattern topicPattern() {
        return PATTERN;
    }

    @Override
    public void handle(String deviceIdentity, String payload) {
        String deviceNo = null;
        try {
            deviceNo = deviceIdentityResolver.resolveDeviceNo(deviceIdentity);
            if (deviceNo == null) {
                log.warn("[MQTT] 设备电量上报未找到设备 时间={} 设备标识={} 消息体={}",
                    HandlerLogTime.now(), deviceIdentity, payload);
                return;
            }
            Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
            if (dto == null || dto.get("powerLevel") == null) {
                log.warn("[MQTT] 设备电量上报缺少电量字段 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
                return;
            }
            // 有效电量上报同时作为设备在线心跳。
            AppDeviceBo appDeviceBo = new AppDeviceBo();
            appDeviceBo.setDeviceNo(deviceNo);
            appDeviceBo.setPowerLevel(dto.get("powerLevel").toString());
            appDeviceBo.setPowerLevelUpdatatime(new Date());
            appDeviceService.updateByBo(appDeviceBo);
            deviceStatusService.markOnline(deviceNo);
            log.info("[MQTT] 设备电量更新并刷新在线心跳 时间={} 设备编号={} 消息体={}",
                HandlerLogTime.now(), deviceNo, payload);
        } catch (Exception e) {
            log.error("[MQTT] 设备电量更新失败 时间={} 设备标识={} 设备编号={} 消息体={}",
                HandlerLogTime.now(), deviceIdentity, deviceNo, payload, e);
        }
    }
}
