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

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import static com.yc.ship.module.trade.enums.TradeMqConstants.*;
import static com.yc.ship.module.trade.framework.mq.TradeMqConfig.DL_QUEUE_INSURANCE_QUERY;


/**
 * &#064;Description ：交易类Mq消息发布工具
 * &#064;Author ：qsl
 * &#064;Date ：2025/6/21 09:18
 */
@Slf4j
@Component
public class TradePublishUtils {

    @Resource
    private RabbitTemplate template;

    /**
     * 发布订单创建成功消息
     * @param message
     */
    public void publishOrderCreateSuccessMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_createSuccess");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_CREATE_SUCCESS,message,correlationData);
    }

    /**
     * 发布订单创建失败消息
     * @param message
     */
    public void publishOrderCreateFailMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_createFail");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_CREATE_FAIL,message,correlationData);
    }

    /**
     * 发布订单支付超时消息
     * @param message
     */
    public void publishOrderPayTimeOutMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_payTimeOut");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_PAY_TIMEOUT,message,correlationData);
    }

    /**
     * 发布订单出票成功消息
     * @param message
     */
    public void publishProcessSuccessMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_processSuccess");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_PROCESS_SUCCESS,message,correlationData);
    }

    /**
     * 发布订单出票失败消息
     * @param message
     */
    public void publishProcessFailMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_processFail");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_PROCESS_FAIL,message,correlationData);
    }

    /**
     * 发布订单支付延迟消息，用于处理支付超时情况
     * @param data 消息体
     * @param delay 延迟时间 毫秒
     */
    public void publishOrderPayDelayMsg(String data, long delay){
        CorrelationData correlationData = new CorrelationData(data+"_payDelayMsg");
        template.convertAndSend(EXCHANGE_ORDER, DELAY_ROUTE_ORDER_PAY, data, message -> {
            // 设置延迟毫秒值
            message.getMessageProperties().setExpiration(String.valueOf((delay == 0) ? 60 * 1000 : delay));
            return message;
        },correlationData);
    }

    /**
     * 发布供应商退款成功消息
     * @param message
     */
    @Retryable(
            maxAttempts = 1,              // 最大重试次数
            value = { Exception.class },  // 重试的异常类型
            backoff = @Backoff(delay = 5000, maxDelay = 5000, multiplier = 2)  // 重试延时策略
    )
    public void publishSupplierRefundSuccessMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_refund");
        Boolean flag = template.invoke(operations->{
            template.convertAndSend(EXCHANGE_ORDER,ROUTE_SUPPLIER_REFUND_SUCCESS,message,correlationData);
            return template.waitForConfirms(5000);
        });

        if (flag == null || !flag) {
            throw new RuntimeException("发布供应商退款成功消息失败");
        }
    }

    /**
     * 发布退款审核结果消息
     * @param message
     */
    public void publishRefundAuditMsg(String message){
        CorrelationData correlationData = new CorrelationData(message+"_refundAuditMsg");
        template.convertAndSend(EXCHANGE_ORDER,ROUTE_REFUND_AUDIT,message,correlationData);
    }

    /**
     * 发布二次确认订单延迟消息，用于指定时间内确认订单，不确认自动退款
     * @param data 消息体
     * @param delay 延迟时间 毫秒
     */
    public void publishConfirmOrderDelayMsg(String data, long delay){
        CorrelationData correlationData = new CorrelationData(data+"_confirmDelayMsg");
        template.convertAndSend(EXCHANGE_ORDER, DELAY_ROUTE_ORDER_CONFIRM, data, message -> {
            // 设置延迟毫秒值
            message.getMessageProperties().setExpiration(String.valueOf((delay == 0) ? 60 * 1000 : delay));
            return message;
        },correlationData);
    }

    /**
     * 发布核销订单成功消息
     *
     * @param message 消息
     */
    public void checkOrderSuccessMsg(String message) {
        template.convertAndSend(EXCHANGE_ORDER, ROUTE_CHECK_ORDER_SUCCESS, message);
    }

    /**
     * 发布修改订单状态延迟消息
     * @param data 消息体
     */
    @Retryable(
            maxAttempts = 3,              // 最大重试次数
            value = { Exception.class },  // 重试的异常类型
            backoff = @Backoff(delay = 5000, maxDelay = 5000, multiplier = 2)  // 重试延时策略
    )
    public void updateOrderStatusMsg(String data) {
        Boolean flag = template.invoke(operations -> {
            template.convertAndSend(EXCHANGE_ORDER, DELAY_ROUTE_UPDATE_ORDER_STATUS, data, message -> {
                // 设置延迟毫秒值
                message.getMessageProperties().setExpiration((60 * 1000) + "");
                return message;
            });
            return template.waitForConfirms(5000);
        });
        if (flag == null || !flag) {
            throw new RuntimeException("发布核销检查延时消息失败");
        }
    }

    /**
     * 发布核销门票成功消息
     *
     * @param message 消息
     */
    public void checkVoucherSuccessMsg(String message) {
        template.convertAndSend(EXCHANGE_ORDER, ROUTE_CHECK_VOUCHER_SUCCESS, message);
    }

    /**
     * 发布核销子票成功消息
     *
     * @param message 消息
     */
    public void checkVoucherBaseSuccessMsg(String message) {
        template.convertAndSend(EXCHANGE_ORDER, ROUTE_CHECK_VOUCHER_BASE_SUCCESS, message);
    }

    /**
     * 发布核销通知延时消息
     * @param data 消息体
     * @param delay 延迟时间 毫秒
     */
    public void publishCheckNotifyDelayMsg(String data, long delay){
        template.convertAndSend(EXCHANGE_ORDER, DELAY_ROUTE_CHECK_NOTIFY, data, message -> {
            // 设置延迟毫秒值
            message.getMessageProperties().setExpiration(String.valueOf((delay == 0) ? 60 * 1000 : delay));
            return message;
        });
    }

    /**
     * 营销政策审核成功通知
     * @param message
     */
    public void marketingAuditSuccessMsg(String message){
        template.convertAndSend(EXCHANGE_ORDER,MARKETING_ORDER_AUDIT,message);
    }

    @Retryable(
            maxAttempts = 1,              // 最大重试次数
            value = { Exception.class },  // 重试的异常类型
            backoff = @Backoff(delay = 5000, maxDelay = 5000, multiplier = 2)  // 重试延时策略
    )
    public void publishOtaProductPriceStockNotifyMsg(String data){
        Boolean flag = template.invoke(operations -> {
            template.convertAndSend(EXCHANGE_ORDER, DELAY_OTA_PRODUCT_PRICE_STOCK, data, message -> {
                message.getMessageProperties().setExpiration((30 * 1000) + "");
                return message;
            });
            return template.waitForConfirms(5000);
        });
        if (flag == null || !flag) {
            throw new RuntimeException("发布核销检查延时消息失败");
        }
    }


    public void publishInsuranceQueryMsg(String message){
        template.convertAndSend(EXCHANGE_ORDER, DL_QUEUE_INSURANCE_QUERY, message);
    }
}
