package com.usky.cdi.service.config.mqtt;

import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author han
 * @date 2025/03/20 14:31
 */
@Component
public class MqttOutConfig {
    public MqttBaseConfig mqttBaseConfig;

    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";

    public static final String MESSAGE_NAME = "messageOut";

    public static final String DEFAULT_TOPIC = "testTopic";

    /**
     * 连接通道
     *
     * @return
     */
    @Bean(name = CHANNEL_NAME_OUT)
    public MessageChannel mqttOutboundChannel() {
        return new DirectChannel();
    }


    /**
     * MQTT消息发送处理器
     * 注意：这个方法会被Spring自动创建，用于处理mqttOutboundChannel通道上的消息
     *
     * @param factory MQTT客户端工厂
     * @return MessageHandler实例
     */
    @Bean(name = MESSAGE_NAME)
    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
    public MessageHandler outbound(DefaultMqttPahoClientFactory factory) {
        // 注意：这里的client-id暂时使用固定值，因为username在启动时还不可用
        // 实际使用时，会在createMqttConnection方法中重新设置
        String clientId = "mqttx-" + System.currentTimeMillis();
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(clientId, factory);
        // 如果设置成true，发送消息时将不会阻塞。
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic(DEFAULT_TOPIC);
        return messageHandler;
    }

    /**
     * MQTT客户端工厂
     * 注意：这个方法会被Spring自动创建，用于创建MQTT客户端
     *
     * @return DefaultMqttPahoClientFactory实例
     */
    @Bean
    public DefaultMqttPahoClientFactory mqttClientFactory() {
        // 创建默认的MqttPahoClientFactory
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();

        // 设置默认的MqttConnectOptions，确保serverURIs不为null
        // 使用时，会在createMqttConnection方法中重新配置
        MqttConnectOptions options = new MqttConnectOptions();
        // 设置默认的服务器地址
        options.setServerURIs(new String[]{"ssl://114.80.201.143:8883"});
        // 设置默认的心跳间隔
        options.setKeepAliveInterval(60);
        factory.setConnectionOptions(options);

        return factory;
    }

    // 注意：这个接口需要被Spring扫描到，所以我们保留@MessagingGateway注解
    // Spring会自动创建这个接口的实现类
    @MessagingGateway(defaultRequestChannel = CHANNEL_NAME_OUT)
    public interface MqttGateway {
        /**
         * 发送消息
         *
         * @param payload
         */
        void sendToMqtt(String payload);

        /**
         * 指定top发送消息
         *
         * @param topic
         * @param payload
         */
        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);

        /**
         * 指定top发送消息
         *
         * @param topic
         * @param payload
         */
        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, Map<String, Object> payload);

        /**
         * 指定队列和qos
         *
         * @param topic
         * @param qos
         * @param payload
         */
        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
    }
}