package com.wzj.soopin.im.consumer;

import com.wzj.soopin.im.service.IMQMessageHandleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mq.config.RocketMQConfig;
import org.dromara.common.mq.domain.MQMessage;
import org.springframework.stereotype.Component;

/**
 * RocketMQ消息消费者
 *
 * @author wzj
 */
@Slf4j
@Component
@RequiredArgsConstructor
@RocketMQMessageListener(
    topic = RocketMQConfig.TOPIC_IM_MSG,
//    consumerGroup = RocketMQConfig.CONSUMER_GROUP_SYS_MSG,
    consumerGroup = "cosumer",
    selectorExpression = "*"
//    ackMode = AckMode.MANUAL
)
public class MessageRocketMQConsumer implements RocketMQListener<MessageExt> {

    private final IMQMessageHandleService messageHandleService;

    @Override
    public void onMessage(MessageExt messageExt) {  // 参数为MessageExt
        String message = new String(messageExt.getBody());
        log.info("接收到RocketMQ消息: {}, msgId: {}", message, messageExt.getMsgId());

        try {
            MQMessage mqMessage = JsonUtils.parseObject(message, MQMessage.class);
            if (mqMessage != null) {
                boolean result = messageHandleService.handleMessage(mqMessage);
                if (result) {
                    // 消息处理成功，手动确认
//                    messageExt.acknowledge();  // 2.3.1版本支持该方法
                    log.info("消息确认成功, msgId: {}", messageExt.getMsgId());
                } else {
                    // 业务失败，抛出异常触发重试
                    throw new RuntimeException("业务处理失败，将重试");
                }
            } else {
                log.warn("消息格式错误，直接确认避免重试: {}", message);
//                messageExt.acknowledge();  // 格式错误无需重试
            }
        } catch (Exception e) {
            log.error("消息处理异常, msgId: {}", messageExt.getMsgId(), e);
            // 达到最大重试次数后确认消息
            if (messageExt.getReconsumeTimes() >= 3) {
                log.error("达到最大重试次数，确认消息进入死信队列, msgId: {}", messageExt.getMsgId());
//                messageExt.acknowledge();
            } else {
                // 未达重试上限，抛出异常触发重试
                throw new RuntimeException("消息处理异常，将重试", e);
            }
        }
    }

}
