package com.smyhub.store.mengyastorebackendjava.mq;

import com.rabbitmq.client.Channel;
import com.smyhub.store.mengyastorebackendjava.service.EmailService;
import com.smyhub.store.mengyastorebackendjava.service.SiteService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(name = "app.rabbitmq-enabled", havingValue = "true")
public class OrderEmailConsumer {

    private final SiteService siteService;
    private final EmailService emailService;

    @RabbitListener(queues = "#{T(com.smyhub.store.mengyastorebackendjava.mq.RabbitMQTopology).queueName(@appProperties.rabbitmqEnv)}", ackMode = "MANUAL")
    public void onMessage(OrderEmailPayload payload, Message message, Channel channel,
                          @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
        if (payload == null || payload.getToEmail() == null || payload.getToEmail().isBlank()) {
            channel.basicAck(deliveryTag, false);
            return;
        }

        SiteService.SmtpConfig cfg = siteService.getSmtpConfig();
        if (!cfg.isConfigured()) {
            log.info("[MQ] skip email order={}: smtp not configured", payload.getOrderId());
            channel.basicAck(deliveryTag, false);
            return;
        }

        EmailService.OrderNotifyData data = new EmailService.OrderNotifyData();
        data.toEmail = payload.getToEmail();
        data.toName = payload.getToName();
        data.productName = payload.getProductName();
        data.orderId = payload.getOrderId();
        data.quantity = payload.getQuantity();
        data.codes = payload.getCodes();
        data.isManual = payload.isManual();

        try {
            emailService.sendOrderNotify(cfg, data);
            channel.basicAck(deliveryTag, false);
            log.info("[MQ] email ok order={} to={}", payload.getOrderId(), payload.getToEmail());
        } catch (Exception e) {
            log.warn("[MQ] send email fail order={}: {}", payload.getOrderId(), e.getMessage());
            boolean redelivered = message.getMessageProperties().isRedelivered();
            if (redelivered) {
                log.warn("[MQ] drop order={} after failed redelivery", payload.getOrderId());
                channel.basicAck(deliveryTag, false);
            } else {
                channel.basicNack(deliveryTag, false, true);
            }
        }
    }
}
