package com.luojia_channel.modules.message.mq;

import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
// 模板方法类，提供消息发送的模板方法
public abstract class AbstractSendProduceTemplate<T> {

    private final RabbitTemplate rabbitTemplate;
    private static final String KEYS = "keys";

    protected abstract BaseSendExtendDTO buildBaseSendParam(T messageSendEvent);

    public void sendMessage(T messageSendEvent) {
        BaseSendExtendDTO baseSendDTO = buildBaseSendParam(messageSendEvent);
        try {
            // 发送消息
            rabbitTemplate.convertAndSend(
                    baseSendDTO.getExchange(),
                    baseSendDTO.getRoutingKey(),
                    new MessageWrapper(baseSendDTO.getKeys(), messageSendEvent),
                    m -> {
                        // 设置消息头
                        m.getMessageProperties().setHeader(KEYS, baseSendDTO.getKeys());
                        // 设置消息属性（如延迟时间）
                        if (baseSendDTO.getDelay() != null) {
                            m.getMessageProperties().setExpiration(baseSendDTO.getDelay().toString());
                        }
                        return m;
                    }
            );
            log.info("[{}] 消息发送成功，Exchange：{}，Routing Key：{}",
                    baseSendDTO.getEventName(), baseSendDTO.getExchange(), baseSendDTO.getRoutingKey());
        } catch (Throwable ex) {
            log.error("[{}] 消息发送失败，消息体：{}", baseSendDTO.getEventName(), JSON.toJSONString(messageSendEvent), ex);
            throw ex;
        }
    }
}
