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.DoorSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.EnvSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.SmartSocketHandler;
import com.shzg.project.worn.sensor.mqtt.handler.SmokeSensorHandler;
import com.shzg.project.worn.sensor.mqtt.handler.SwitchHandler;
import com.shzg.project.worn.sensor.mqtt.handler.WaterSensorHandler;
import com.shzg.project.worn.service.IMqttSensorDeviceService;
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;

@Slf4j
@Component
public class MqttMessageDispatcher {

    @Autowired
    private MqttDeviceCache deviceCache;

    @Autowired
    private IMqttSensorDeviceService deviceService;

    @Autowired
    private SmokeSensorHandler smokeSensorHandler;

    @Autowired
    private EnvSensorHandler envSensorHandler;

    @Autowired
    private WaterSensorHandler waterSensorHandler;

    @Autowired
    private SmartSocketHandler smartSocketHandler;

    @Autowired
    private DoorSensorHandler doorSensorHandler;

    @Autowired
    private SwitchHandler switchHandler;

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

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    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 {
            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();

            MqttSensorDevice device = deviceCache.get(devEui);
            if (device == null) {
                log.warn("[MQTT] cache miss, devEUI={}", devEui);
                device = deviceService.selectByDevEui(devEui);
                if (device == null) {
                    log.warn("[MQTT] db fallback miss, devEUI={}", devEui);
                    return;
                }
                deviceCache.put(device);
                log.info("[MQTT] db fallback hit and cache restored, devEUI={}, status={}", devEui, device.getStatus());
            }

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

            deviceType = deviceType.toLowerCase();

            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;
            }

            if (deviceType.contains("switch")) {
                switchHandler.handle(device, topic, payload);
                return;
            }

            log.warn("[MQTT] 未识别设备类型 deviceType={}, devEUI={}", deviceType, devEui);
        } catch (Exception e) {
            log.error("[MQTT] 分发异常 topic=" + topic + ", payload=" + payload, e);
        }
    }
}
