package com.fuyuanshen.global.mqtt.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fuyuanshen.global.mqtt.base.MqttMessage;
import com.fuyuanshen.global.mqtt.service.IotMqttService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;

/**
 * 通用IoT设备MQTT协议服务实现类
 * 遵循统一的MQTT通信协议规范
 */
@Slf4j
@Service
public class IotMqttServiceImpl implements IotMqttService {

    @Autowired
    private ApplicationContext applicationContext;

    // MQTT主题前缀
    private static final String COMMAND_PREFIX = "command";
    private static final String STATUS_PREFIX = "status";
    private static final String REPORT_PREFIX = "report";

    @Override
    public String buildCommandTopic(String tenantCode, Long deviceType, String imei) {
        return String.format("%s/%s/%s/%s", COMMAND_PREFIX, tenantCode, deviceType, imei);
    }

    @Override
    public String buildStatusTopic(String tenantCode, String deviceType, String imei) {
        return String.format("%s/%s/%s/%s", STATUS_PREFIX, tenantCode, deviceType, imei);
    }

    @Override
    public String buildReportTopic(String tenantCode, String deviceType, String imei) {
        return String.format("%s/%s/%s/%s", REPORT_PREFIX, tenantCode, deviceType, imei);
    }

    @Override
    public void sendCommand(String tenantCode, Long deviceType, String imei, MqttMessage message) {
        String topic = buildCommandTopic(tenantCode, deviceType, imei);
        String payload = JSON.toJSONString(message);
        sendMqttMessage(topic, 1, payload);
        log.info("发送指令到设备: topic={}, payload={}", topic, payload);
    }

    @Override
    public void sendStatus(String tenantCode, String deviceType, String imei, JSONObject message) {
        String topic = buildStatusTopic(tenantCode, deviceType, imei);
        String payload = message.toJSONString();
        sendMqttMessage(topic, 1, payload);
        log.info("发送响应消息到设备: topic={}, payload={}", topic, payload);
    }

    @Override
    public void sendReportAck(String tenantCode, String deviceType, String imei, JSONObject message) {
        String topic = buildReportTopic(tenantCode, deviceType, imei);
        String payload = message.toJSONString();
        sendMqttMessage(topic, 1, payload);
        log.info("发送设备上报数据确认消息: topic={}, payload={}", topic, payload);
    }

    @Override
    public void handleSingleReport(String tenantCode, String deviceType, String imei,
                                   String sensor, Object value, Long timestamp) {
        log.info("处理设备上报的单个传感器数据: tenantCode={}, deviceType={}, imei={}, sensor={}, value={}, timestamp={}",
                tenantCode, deviceType, imei, sensor, value, timestamp);

        // TODO: 实现具体的业务逻辑，如更新设备状态、存储传感器数据等
    }

    @Override
    public void handleBatchReport(String tenantCode, String deviceType, String imei,
                                  JSONObject batchData, Long timestamp) {
        log.info("处理设备上报的批量传感器数据: tenantCode={}, deviceType={}, imei={}, batchData={}, timestamp={}",
                tenantCode, deviceType, imei, JSON.toJSONString(batchData), timestamp);

        // TODO: 实现具体的业务逻辑，如批量更新设备状态、存储传感器数据等
    }

    @Override
    public void handleCommandResponse(String tenantCode, String deviceType, String imei, JSONObject message) {
        log.info("处理设备对指令的响应: tenantCode={}, deviceType={}, imei={}, message={}",
                tenantCode, deviceType, imei, JSON.toJSONString(message));

        // TODO: 实现具体的业务逻辑，如更新指令执行状态等
    }

    /**
     * 通过反射方式发送MQTT消息
     *
     * @param topic   主题
     * @param qos     服务质量等级
     * @param payload 消息内容
     */
    private void sendMqttMessage(String topic, int qos, String payload) {
        try {
            Object mqttGateway = applicationContext.getBean("mqttGateway");
            Method sendMethod = mqttGateway.getClass().getMethod("sendMsgToMqtt", String.class, int.class, String.class);
            sendMethod.invoke(mqttGateway, topic, qos, payload);
        } catch (Exception e) {
            log.error("发送MQTT消息失败: topic={}, payload={}", topic, payload, e);
        }
    }
}