package com.tashow.cloud.mq.rabbitmq.producer;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tashow.cloud.common.util.json.JsonUtils;
import com.tashow.cloud.mq.core.BaseMqMessage;
import com.tashow.cloud.mq.handler.FailRecordHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import jakarta.annotation.PostConstruct;
import java.util.UUID;

/**
 * RabbitMQ消息生产者抽象类
 *
 * @param <T> 消息类型
 * @author tashow
 */
public abstract class AbstractRabbitMQProducer<T extends BaseMqMessage> 
        implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

    private static final Logger log = LoggerFactory.getLogger(AbstractRabbitMQProducer.class);

    @Autowired
    protected RabbitTemplate rabbitTemplate;
    
    @Autowired(required = false)
    protected FailRecordHandler failRecordHandler;

    /**
     * 初始化RabbitTemplate
     */
    @PostConstruct
    public void initRabbitTemplate() {
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback(this);
        rabbitTemplate.setConfirmCallback(this);
        if (rabbitTemplate.isConfirmListener()) {
            log.info("[MQ生产者] 确认回调已正确配置");
        } else {
            log.error("[MQ生产者] 确认回调配置失败");
        }
    }





    /**
     * 异步发送消息，使用指定的correlationId
     *
     * @param message 消息对象
     */
    public void asyncSendMessage(T message) {
        try {
            String messageJson = JsonUtils.toJsonString(message);
            CorrelationData correlationData = new CorrelationData(messageJson);
            failRecordHandler.saveMessageRecord(
                message.getId(),
                getExchange(),
                getRoutingKey(),
                null,
                messageJson,
                0
            );
            rabbitTemplate.convertAndSend(getExchange(), getRoutingKey(), message, correlationData);
        } catch (Exception e) {
            throw e;
        }
    }
    /**
     * 获取交换机名称
     *
     * @return 交换机名称
     */
    public abstract String getExchange();
    /**
     * 获取路由键
     *
     * @return 路由键
     */
    public abstract String getRoutingKey();

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        JSONObject jsonObject = JSON.parseObject(correlationData.getId());
        Integer id =  jsonObject.getInteger("id");
        if (ack) {
          failRecordHandler.updateMessageStatus(id);
        } else {
            failRecordHandler.updateMessageStatusWithCause(id,cause);
        }
    }

} 