package com.shzg.project.worn.sensor.mqtt.dispatcher;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shzg.project.worn.domain.MqttSensorDevice;
import com.shzg.project.worn.sensor.mqtt.handler.EnvSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.SmokeSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.WaterSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.SmartSocketHandler;
import com.shzg.project.worn.sensor.mqtt.handler.DoorSensorHandler;
import com.shzg.project.worn.unit.MqttDeviceCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executor;

/**
 * MQTT消息分发器（支持烟雾 / 环境 / 水浸 / 插座 / 门磁）
 */
@Slf4j
@Component
public class MqttMessageDispatcher {

    @Autowired
    private MqttDeviceCache deviceCache;

    @Autowired
    private SmokeSensorHandler smokeSensorHandler;

    @Autowired
    private EnvSensorHandler envSensorHandler;

    @Autowired
    private WaterSensorHandler waterSensorHandler;

    @Autowired
    private SmartSocketHandler smartSocketHandler;

    @Autowired
    private DoorSensorHandler doorSensorHandler;

    @Autowired
    @Qualifier("mqttExecutor")
    private Executor executor;

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /**
     * MQTT入口（异步）
     */
    public void dispatch(String topic, String payload) {
        executor.execute(() -> doDispatch(topic, payload));
    }

    /**
     * 核心分发逻辑
     */
    private void doDispatch(String topic, String payload) {

        log.info("[MQTT] 收到消息 topic={}, payload={}", topic, payload);

        try {
            // =========================
            // 1️⃣ JSON解析
            // =========================
            JsonNode root = OBJECT_MAPPER.readTree(payload);

            if (!root.has("devEUI")) {
                log.warn("[MQTT] payload中未找到devEUI");
                return;
            }

            String devEui = root.get("devEUI").asText();

            if (devEui == null || devEui.isEmpty()) {
                log.warn("[MQTT] devEUI为空");
                return;
            }

            devEui = devEui.toLowerCase();

            // =========================
            // 2️⃣ 获取设备
            // =========================
            MqttSensorDevice device = deviceCache.get(devEui);

            if (device == null) {
                log.warn("[MQTT] 未匹配设备 devEUI={}", devEui);
                return;
            }

            String deviceType = device.getDeviceType();

            if (deviceType == null || deviceType.isEmpty()) {
                log.warn("[MQTT] device_type为空 devEUI={}", devEui);
                return;
            }

            deviceType = deviceType.toLowerCase();

            // =========================
            // 3️⃣ 分发（核心）
            // =========================

            // 烟雾
            if (deviceType.contains("smoke")) {
                smokeSensorHandler.handle(device, topic, payload);
                return;
            }

            // 环境
            if (deviceType.contains("env")) {
                envSensorHandler.handle(device, topic, payload);
                return;
            }

            // 水浸
            if (deviceType.contains("water")) {
                waterSensorHandler.handle(device, topic, payload);
                return;
            }

            // 智能插座
            if (deviceType.contains("socket")) {
                smartSocketHandler.handle(device, topic, payload);
                return;
            }

            // 门磁
            if (deviceType.contains("door")) {
                doorSensorHandler.handle(device, topic, payload);
                return;
            }

            // ❌ 未识别
            log.warn("[MQTT] 未识别设备类型 deviceType={}", deviceType);

        } catch (Exception e) {
            log.error("[MQTT] 分发异常 topic=" + topic + ", payload=" + payload, e);
        }
    }
}