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.Map;
import java.util.regex.Pattern;

/**
 * Device registration handler, matches /{deviceNo}/publish/register.
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceRegisterHandler implements MqttTopicHandler {

    private static final Pattern PATTERN = Pattern.compile("^/([^/]+)/publish/register$");

    private final IAppDeviceService appDeviceService;

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

    @Override
    public void handle(String deviceNo, String payload) {
        try {
            Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
            AppDeviceBo device = buildRegisterDevice(deviceNo, dto);
            appDeviceService.registerByMqtt(device);
            log.info("[MQTT] 设备注册 deviceNo={} payload={}", deviceNo, payload);
        } catch (Exception e) {
            log.error("[MQTT] 设备注册失败 deviceNo={} payload={}", deviceNo, payload, e);
        }
    }

    private AppDeviceBo buildRegisterDevice(String topicDeviceNo, Map<String, Object> dto) {
        AppDeviceBo device = new AppDeviceBo();
        device.setDeviceNo(topicDeviceNo);
        if (dto == null) {
            return device;
        }
        device.setDeviceName(valueAsString(dto.get("deviceName")));
        device.setPowerLevel(valueAsString(dto.get("powerLevel")));
        device.setDeviceEm(valueAsString(dto.get("deviceEm")));
        device.setDeviceSn(valueAsString(dto.get("deviceSn")));
        device.setMacAddress(firstNotBlank(dto.get("deviceMac"), dto.get("macAddress")));
        device.setFwVer(firstNotBlank(dto.get("version"), dto.get("fwVer")));
        return device;
    }

    private String firstNotBlank(Object first, Object second) {
        String firstText = valueAsString(first);
        if (firstText != null && !firstText.isBlank()) {
            return firstText;
        }
        String secondText = valueAsString(second);
        return secondText != null && !secondText.isBlank() ? secondText : null;
    }

    private String valueAsString(Object value) {
        return value == null ? null : String.valueOf(value);
    }
}
