package com.tashow.cloud.mq.rabbitmq.consumer;
import com.rabbitmq.client.Channel;
import com.tashow.cloud.mq.core.BaseMqMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;

/**
 * RabbitMQ消息消费者抽象类
 *
 * @param <T> 消息类型
 * @author tashow
 */
public abstract class AbstractRabbitMQConsumer<T extends BaseMqMessage> {

    private static final Logger log = LoggerFactory.getLogger(AbstractRabbitMQConsumer.class);
    /**
     * 消息状态：成功
     */
    public static final int STATUS_SUCCESS = 20;
    /**
     * 消息状态：消费异常
     */
    public static final int STATUS_SEND_EXCEPTION = 30;


    /**
     * 埋点处理消息
     *
     * @param message 消息对象
     * @return 处理结果，true表示处理成功，false表示处理失败
     */
    public abstract boolean processMessage(T message);


    /**
     * 消息处理入口
     *
     * @param message     消息对象
     * @param channel     通道
     * @param deliveryTag 投递标签
     */
    public void onMessage(T message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        message.setStatusCode(STATUS_SUCCESS);
        try {
            if(true){
                throw new RuntimeException("测试异常");
            }
            processMessage(message);
            safeChannelAck(channel, deliveryTag);
        } catch (Exception e) {
            message.setStatusCode(STATUS_SEND_EXCEPTION);
            processMessage( message);
            safeChannelAck(channel, deliveryTag);

        }
    }

    /**
     * 安全确认消息
     *
     * @param channel     通道
     * @param deliveryTag 投递标签
     */
    protected void safeChannelAck(Channel channel, long deliveryTag) {
        try {
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            log.error("[MQ消费者] 确认消息失败: {}", e.getMessage());
        }
    }

    /**
     * 安全拒绝消息
     *
     * @param channel     通道
     * @param deliveryTag 投递标签
     * @param multiple    是否批量
     * @param requeue     是否重新入队
     */
    protected void safeChannelNack(Channel channel, long deliveryTag, boolean multiple, boolean requeue) {
        try {
            channel.basicNack(deliveryTag, multiple, requeue);
        } catch (Exception e) {
            log.error("[MQ消费者] 拒绝消息失败: {}", e.getMessage());
        }
    }
} 