package com.yc.ship.module.trade.framework.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

import static com.yc.ship.module.trade.enums.TradeMqConstants.*;


/**
 * &#064;Description ：交易类Mq配置
 * &#064;Author ：qsl
 * &#064;Date ：2025/6/21 09:18
 */
@Configuration
@Slf4j
public class TradeMqConfig {

    public static final String QUEUE_CREATE_SUCCESS ="queue_order_create_success";
    public static final String QUEUE_CREATE_FAIL ="queue_order_create_fail";
    public static final String QUEUE_PAY_TIMEOUT ="queue_order_pay_timeout";
    public static final String QUEUE_PROCESS_SUCCESS ="queue_order_process_success";
    public static final String QUEUE_PROCESS_FAIL ="queue_order_process_fail";
    public static final String QUEUE_SUPPLIER_REFUND_SUCCESS ="queue_supplier_refund_success";
    public static final String QUEUE_REFUND_AUDIT ="queue_refund_audit";

    public static final String QUEUE_CHECK_ORDER_SUCCESS ="queue_check_order_success";
    public static final String QUEUE_CHECK_VOUCHER_SUCCESS ="queue_check_voucher_success";
    public static final String QUEUE_CHECK_VOUCHER_BASE_SUCCESS ="queue_check_voucher_base_success";

    public static final String DL_QUEUE_ORDER_PAY ="dl_queue_order_pay";
    public static final String DL_QUEUE_ORDER_CONFIRM ="dl_queue_order_confirm";
    public static final String DL_QUEUE_CHECK_NOTIFY ="dl_queue_check_notify";
    public static final String DL_QUEUE_UPDATE_ORDER_STATUS ="dl_queue_update_order_status";
    public static final String DELAY_QUEUE_ORDER_PAY ="delay_queue_order_pay";
    public static final String DELAY_QUEUE_ORDER_CONFIRM ="delay_queue_order_confirm";
    public static final String DELAY_QUEUE_CHECK_NOTIFY ="delay_queue_trade_check_notify";
    public static final String DELAY_QUEUE_UPDATE_ORDER_STATUS ="delay_queue_update_order_status";

    public static final String ORDER_MARKETING_AUDIT ="order_marketing_audit";
    public static final String DL_QUEUE_OTA_NOTIFY ="dl_queue_ota_notify";
    public static final String DELAY_QUEUE_OTA_PRICE_STOCK ="delay_queue_ota_price_stock";

    /**
     * 保险延迟反查
     */
    public static final String DL_QUEUE_INSURANCE_QUERY ="dl_queue_insurance_query";


    @Bean
    public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
        // 启用生产者确认模式
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        connectionFactory.setPublisherReturns(true);
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        // 设置生产者确认回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (!ack) {
                //暂时不处理
                log.error("消息"+correlationData+"确认失败，原因: " + cause);
            }
        });
        return rabbitTemplate;
    }

    @Bean(name = "marketingAuditQueue")
    public Queue marketingAuditQueue(){
        return new Queue(ORDER_MARKETING_AUDIT);
    }

    @Bean(name = "tradeOrderExchange")
    public TopicExchange tradeOrderExchange(){
        return new TopicExchange(EXCHANGE_ORDER);
    }
    @Bean(name = "orderCreateSuccessQueue")
    public Queue orderCreateSuccessQueue(){
        return new Queue(QUEUE_CREATE_SUCCESS);
    }

    @Bean(name = "orderCreateFailQueue")
    public Queue orderCreateFailQueue(){
        return new Queue(QUEUE_CREATE_FAIL);
    }

    @Bean(name = "orderPayTimeOut")
    public Queue orderPayTimeOut(){
        return new Queue(QUEUE_PAY_TIMEOUT);
    }

    @Bean(name = "orderProcessSuccess")
    public Queue orderProcessSuccess(){
        return new Queue(QUEUE_PROCESS_SUCCESS);
    }

    @Bean(name = "orderProcessFail")
    public Queue orderProcessFail(){
        return new Queue(QUEUE_PROCESS_FAIL);
    }

    @Bean(name = "supplierRefundSuccess")
    public Queue supplierRefundSuccess(){
        return new Queue(QUEUE_SUPPLIER_REFUND_SUCCESS);
    }

    @Bean(name = "refundAuditQueue")
    public Queue refundAuditQueue(){
        return new Queue(QUEUE_REFUND_AUDIT);
    }

    @Bean(name = "checkOrderSuccessQueue")
    public Queue checkOrderSuccessQueue(){
        return new Queue(QUEUE_CHECK_ORDER_SUCCESS);
    }


    @Bean(name = "checkVoucherSuccessQueue")
    public Queue checkVoucherSuccessQueue(){
        return new Queue(QUEUE_CHECK_VOUCHER_SUCCESS);
    }

    @Bean(name = "checkVoucherBaseSuccessQueue")
    public Queue checkVoucherBaseSuccessQueue(){
        return new Queue(QUEUE_CHECK_VOUCHER_BASE_SUCCESS);
    }


    @Bean
    Binding bindOrderCreateSuccess(@Qualifier("orderCreateSuccessQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_CREATE_SUCCESS);
    }

    @Bean
    Binding bindOrderCreateFail(@Qualifier("orderCreateFailQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_CREATE_FAIL);
    }

    @Bean
    Binding bindOrderPayTimeOut(@Qualifier("orderPayTimeOut") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_PAY_TIMEOUT);
    }

    @Bean
    Binding bindProcessSuccess(@Qualifier("orderProcessSuccess") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_PROCESS_SUCCESS);
    }

    @Bean
    Binding bindProcessFail(@Qualifier("orderProcessFail") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_PROCESS_FAIL);
    }

    @Bean
    Binding bindSupplierRefundSuccess(@Qualifier("supplierRefundSuccess") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_SUPPLIER_REFUND_SUCCESS);
    }

    @Bean
    Binding bindRefundAudit(@Qualifier("refundAuditQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_REFUND_AUDIT);
    }

    @Bean
    Binding bindCheckOrderSuccessQueue(@Qualifier("checkOrderSuccessQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_CHECK_ORDER_SUCCESS);
    }

    @Bean
    Binding bindCheckVoucherSuccessQueue(@Qualifier("checkVoucherSuccessQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_CHECK_VOUCHER_SUCCESS);
    }


    @Bean
    Binding bindCheckVoucherBaseSuccessQueue(@Qualifier("checkVoucherBaseSuccessQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTE_CHECK_VOUCHER_BASE_SUCCESS);
    }

    @Bean
    Binding bindMarketingAuditQueue(@Qualifier("marketingAuditQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(MARKETING_ORDER_AUDIT);
    }

    //==============死信交换机配置===========
    @Bean(name = "tradeDeadLetterExchange")
    public TopicExchange tradeDeadLetterExchange(){
        return new TopicExchange(DL_EXCHANGE_ORDER);
    }
    @Bean(name = "orderPayDLQueue")
    public Queue orderPayDLQueue(){
        return new Queue(DL_QUEUE_ORDER_PAY);
    }
    @Bean
    Binding bindPayDLQueue(@Qualifier("orderPayDLQueue") Queue queue, @Qualifier("tradeDeadLetterExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_ROUTE_ORDER_PAY);
    }

    @Bean(name = "orderPayDelayQueue")
    public Queue orderPayDelayQueue(){
        return QueueBuilder.durable(DELAY_QUEUE_ORDER_PAY)
                // 配置到期后转发的交换
                .withArgument("x-dead-letter-exchange",DL_EXCHANGE_ORDER)
                // 配置到期后转发的路由键
                .withArgument("x-dead-letter-routing-key",DL_ROUTE_ORDER_PAY)
                .build();
    }

    @Bean
    public Binding bindOrderPayDelay(@Qualifier("orderPayDelayQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange)
                .with(DELAY_ROUTE_ORDER_PAY);
    }


    @Bean(name = "orderConfirmDLQueue")
    public Queue orderConfirmDLQueue(){
        return new Queue(DL_QUEUE_ORDER_CONFIRM);
    }

    @Bean
    Binding binConfirmDLQueue(@Qualifier("orderConfirmDLQueue") Queue queue, @Qualifier("tradeDeadLetterExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_ROUTE_ORDER_CONFIRM);
    }

    @Bean(name = "orderConfirmDelayQueue")
    public Queue orderConfirmDelayQueue(){
        return QueueBuilder.durable(DELAY_QUEUE_ORDER_CONFIRM)
                // 配置到期后转发的交换
                .withArgument("x-dead-letter-exchange",DL_EXCHANGE_ORDER)
                // 配置到期后转发的路由键
                .withArgument("x-dead-letter-routing-key",DL_ROUTE_ORDER_CONFIRM)
                .build();
    }

    @Bean
    public Binding bindOrderConfirmDelay(@Qualifier("orderConfirmDelayQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange)
                .with(DELAY_ROUTE_ORDER_CONFIRM);
    }



    @Bean(name = "orderCheckDLQueue")
    public Queue orderCheckDLQueue(){
        return new Queue(DL_QUEUE_CHECK_NOTIFY);
    }

    @Bean
    Binding bindCheckDLQueue(@Qualifier("orderCheckDLQueue") Queue queue, @Qualifier("tradeDeadLetterExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_ROUTE_ORDER_CHECK);
    }

    @Bean(name = "checkDelayQueue")
    public Queue checkDelayQueue() {
        return QueueBuilder.durable(DELAY_QUEUE_CHECK_NOTIFY)
                // 配置到期后转发的交换
                .withArgument("x-dead-letter-exchange", DL_EXCHANGE_ORDER)
                // 配置到期后转发的路由键
                .withArgument("x-dead-letter-routing-key", DL_ROUTE_ORDER_CHECK)
                .build();
    }

    @Bean
    public Binding bindingCheckNotifyDelay(@Qualifier("checkDelayQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DELAY_ROUTE_CHECK_NOTIFY);
    }


    @Bean(name = "updateOrderStatusDLQueue")
    public Queue updateOrderStatusDLQueue(){
        return new Queue(DL_QUEUE_UPDATE_ORDER_STATUS);
    }
    @Bean
    Binding bindUpdateOrderStatusDLQueue(@Qualifier("updateOrderStatusDLQueue") Queue queue, @Qualifier("tradeDeadLetterExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_ROUTE_UPDATE_ORDER_STATUS);
    }

    @Bean(name = "updateOrderStatusQueue")
    public Queue updateOrderStatusQueue(){
        return QueueBuilder.durable(DELAY_QUEUE_UPDATE_ORDER_STATUS)
                // 配置到期后转发的交换
                .withArgument("x-dead-letter-exchange", DL_EXCHANGE_ORDER)
                // 配置到期后转发的路由键
                .withArgument("x-dead-letter-routing-key", DL_ROUTE_UPDATE_ORDER_STATUS)
                .build();
    }
    @Bean
    Binding bindUpdateOrderStatusQueue(@Qualifier("updateOrderStatusQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DELAY_ROUTE_UPDATE_ORDER_STATUS);
    }


    @Bean(name = "otaProductPriceStockDLQueue")
    public Queue otaProductPriceStockDLQueue(){
        return new Queue(DL_QUEUE_OTA_NOTIFY);
    }
    @Bean
    Binding bindOtaProductPriceStockDLQueue(@Qualifier("otaProductPriceStockDLQueue") Queue queue, @Qualifier("tradeDeadLetterExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_OTA_PRODUCT_PRICE_STOCK);
    }

    @Bean(name = "otaProductPriceStockQueue")
    public Queue otaProductPriceStockQueue(){
        return QueueBuilder.durable(DELAY_QUEUE_OTA_PRICE_STOCK)
                // 配置到期后转发的交换
                .withArgument("x-dead-letter-exchange", DL_EXCHANGE_ORDER)
                // 配置到期后转发的路由键
                .withArgument("x-dead-letter-routing-key", DL_OTA_PRODUCT_PRICE_STOCK)
                .build();
    }
    @Bean
    Binding bindOtaProductPriceStockQueue(@Qualifier("otaProductPriceStockQueue") Queue queue, @Qualifier("tradeOrderExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DELAY_OTA_PRODUCT_PRICE_STOCK);
    }

    /**
     * 保险交换机
     * @return
     */
    @Bean(name = "insuranceQueryExchange")
    public CustomExchange insuranceQueryExchange(){
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange(DL_EXCHANGE_INSURANCE, "x-delayed-message", true, false, args);
    }
    /**
     * 保险反查队列
     * @return
     */
    @Bean(name = "insuranceQueryQueue")
    public Queue insuranceQueryQueue(){
        return new Queue(DL_QUEUE_INSURANCE_QUERY, true);
    }

    @Bean
    Binding bindInsuranceQueryQueue(@Qualifier("insuranceQueryQueue") Queue queue, @Qualifier("insuranceQueryExchange") CustomExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DL_QUEUE_INSURANCE_QUERY).noargs();
    }
}
