package com.ruoyi.system.forward.mq;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.core.ClientExecute;
import com.ruoyi.system.core.ClientExecuteFactory;
import com.ruoyi.system.core.deviceEntity.ProductEntity;
import com.ruoyi.system.core.deviceEntity.ProductEntityFactory;
import com.ruoyi.system.core.mqtt.DefProtocol;
import com.ruoyi.system.mapper.SysDeviceMapper;
import com.ruoyi.system.util.SpringContextHolder;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;

@Configuration
public class MqttConsumerConfig {

    @Autowired
    private MqttPahoClientFactory mqttClientFactory;

    @Bean
    public MessageChannel mqttInputChannel() {
        return new DirectChannel();
    }

    @Bean
    public MqttPahoMessageDrivenChannelAdapter inbound() {
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(UUID.randomUUID().toString(), mqttClientFactory, "/#");
        adapter.setCompletionTimeout(5000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(mqttInputChannel());
        return adapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel")
    public MessageHandler handler() {
        return message -> {
            String topic = (String) message.getHeaders().get("mqtt_receivedTopic");
            String[] split = topic.split("/");
            String payload = (String) message.getPayload();
            common(split[2], payload);
        };
    }

    @Transactional
    public void common(String deviceNo, String message) {
        JSONObject jsonObject = JSON.parseObject(message);
        if (!jsonObject.containsKey("inputs")) {
            return;
        }
        jsonObject.put("inputs", jsonObject.getJSONArray("inputs").toJSONString());
        DefProtocol defProtocol = JSON.parseObject(jsonObject.toJSONString(), DefProtocol.class);
        SysDeviceMapper deviceMapper = SpringContextHolder.getBean(SysDeviceMapper.class);
        ProductEntityFactory entityFactory = SpringContextHolder.getBean(ProductEntityFactory.class);
        ClientExecuteFactory clientExecuteFactory = SpringContextHolder.getBean(ClientExecuteFactory.class);
        deviceMapper.selectByDeviceNo(deviceNo).subscribe(x -> {
            ProductEntity productEntity = entityFactory.getProductEntity(x.getDeviceType());
            ClientExecute clientExecute = clientExecuteFactory.getClientExecute(x.getConnectionType());
            if (defProtocol.getFunctionId().contains("info_")) {
                productEntity.info(defProtocol, clientExecute, x);
            } else {
                productEntity.put(defProtocol, clientExecute, x);
            }
        });
    }

}