package com.bonus.core.order.mq;

import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.core.common.constant.LeMqConstant;
import com.bonus.core.common.utils.JacksonUtil;
import com.bonus.core.common.utils.LogUtil;
import com.bonus.core.common.utils.SpringContextHolder;
import com.bonus.core.common.utils.TenantContextHolder;
import com.bonus.mq.MQTemplate;
import com.bonus.mq.tx.TxHolder;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;

import java.time.LocalDateTime;

public class MqUtil {
   private static final Logger log = LoggerFactory.getLogger(MqUtil.class);
   @Lazy
   public static final MQTemplate mqTemplate = (MQTemplate) SpringContextHolder.getBean(MQTemplate.class);

   public static <T> void send(T data, LeMqConstant.Topic topic) {
      try {
         log.info("发送消息,topic:{}", topic.getKey());
         LogUtil.printArgs("消息体", data);
         String routing = topic.getKey();
         mqTemplate.send(routing, MqPayload.of(data, topic, routing));
      } catch (Exception var3) {
         log.error("发送MQ消息失败", var3);
      }

   }

   public static <T> void send(T data, LeMqConstant.Topic topic, String routing) {
      try {
         log.info("发送消息,topic:{},routing:{}", topic.getKey(), routing);
         LogUtil.printArgs("消息体", data);
         mqTemplate.send(routing, MqPayload.of(data, topic, routing));
      } catch (Exception var4) {
         log.error("发送MQ消息失败", var4);
      }

   }

   @SneakyThrows
   public static <T> TxHolder sendByTx(T data, LeMqConstant.Topic topic) {
      String routing = topic.getKey();
      log.info("发送事务消息,topic:{}", topic.getKey());
      LogUtil.printArgs("消息体", data);
      return mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing));
   }
   @SneakyThrows
   public static <T> void sendByTxEnd(T data, LeMqConstant.Topic topic) {
      String routing = topic.getKey();
      log.info("发送事务消息,topic:{}", topic.getKey());
      LogUtil.printArgs("消息体", data);
      mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing)).end();
   }
   @SneakyThrows
   public static <T> void sendByTxCommit(T data, LeMqConstant.Topic topic) {
      log.info("发送事务消息,topic:{}", topic.getKey());
      LogUtil.printArgs("消息体", data);
      String routing = topic.getKey();
      mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing)).commit();
   }

   public static <T> void sendDelay(T data, LeMqConstant.Topic topic, int delayMileSecond) {
      try {
         log.info("发送延迟消息,topic:{},delayMileSecond:{}", topic.getKey(), delayMileSecond);
         LogUtil.printArgs("消息体", data);
         String routing = topic.getKey();
         mqTemplate.sendDelay(routing, MqPayload.of(data, topic, routing), (int)delayMileSecond);
      } catch (Exception var4) {
         log.error("发送事务MQ消息失败", var4);
      }

   }

   public static <T> void sendDataChange(T data, LeMqConstant.DataChangeType changeType, LeMqConstant.Topic topic) {
      Long userId = null;

      try {
         userId = SecurityUtils.getUserId();
      } catch (Exception var5) {
      }

      MqDataChangeMessageDto dto = MqDataChangeMessageDto.of(TenantContextHolder.getTenantId(), JacksonUtil.valueToTree(data), changeType, topic, LocalDateTime.now(), SecurityUtils.getUsername(), userId);
      send(dto, topic);
   }

   @SneakyThrows
   public static <T> void pushToSingleDevice(T data, LeMqConstant.Topic topic, String deviceSn) {
      String var10000 = topic.getKey();
      String routing = var10000 + "/" + TenantContextHolder.getTenantId() + "/" + deviceSn;
      log.info("推送给单条设备,routing:{}", routing);
      LogUtil.printArgs("消息体", data);
      mqTemplate.sendMqtt(routing, data);
   }
   @SneakyThrows
   public static <T> void pushToSingleDevice(T data, LeMqConstant.Topic topic, String deviceSn, Long merchantId) {
      String routing = topic.getKey() + "/" + merchantId + "/" + deviceSn;
      log.info("推送给单条设备,routing:{}", routing);
      LogUtil.printArgs("消息体", data);
      mqTemplate.sendMqtt(routing, data);
   }
   @SneakyThrows
   public static <T> void pushToSingleTxDevice(T data, LeMqConstant.Topic topic, String deviceSn) {
      String var10000 = topic.getKey();
      String routing = var10000 + "/" + TenantContextHolder.getTenantId() + "/" + deviceSn;
      log.info("推送给单条设备,routing:{}", routing);
      LogUtil.printArgs("消息体", data);
      mqTemplate.mqttTxBegin(routing, data).end();
   }
   @SneakyThrows
   public static <T> void pushToSingleDevice(T data, String routing, String deviceSn) {
      routing = routing + "/" + TenantContextHolder.getTenantId();
      if (deviceSn != null) {
         routing = routing + "/" + deviceSn;
      }

      log.info("推送给单条设备,routing:{}", routing);
      LogUtil.printArgs("消息体", data);
      mqTemplate.sendMqtt(routing, data);
   }
   @SneakyThrows
   public static <T> void pushToTenantAllDevice(T data, LeMqConstant.Topic topic) {
      String var10000 = topic.getKey();
      String routing = var10000 + "/" + TenantContextHolder.getTenantId();
      log.info("推送给商户下所有设备,routing:{}", routing);
      mqTemplate.sendMqtt(routing, data);
   }
   @SneakyThrows
   public static <T> void pushToTenantAllDeviceWithTenantId(T data, LeMqConstant.Topic topic, Long tenantId) {
      String var10000 = topic.getKey();
      String routing = var10000 + "/" + tenantId;
      log.info("推送给商户下所有设备,routing:{}", routing);
      LogUtil.printArgs("消息体", data);
      mqTemplate.sendMqtt(routing, data);
   }
   @SneakyThrows
   public static <T> void pushToAllDevice(T data, LeMqConstant.Topic topic) {
      mqTemplate.sendMqtt(topic.getKey(), data);
   }
   @SneakyThrows
   public static <T> void pushToSingleDeviceCustomed(T data, String routing) {
      mqTemplate.sendMqtt(routing, data);
   }
}
