package com.erp.order.event;

import com.erp.common.core.event.OrderCancelledEvent;
import com.erp.common.core.event.OrderCreatedEvent;
import com.erp.common.core.event.OrderPaidEvent;
import com.erp.common.core.event.OrderShippedEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单事件发布器 - 当订单发生关键业务动作时发布事件
 * 触发财务记账、库存确认、通知发送等下游处理
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderEventPublisher {

    private final ApplicationEventPublisher eventPublisher;

    /**
     * 发布订单创建事件
     */
    @Async
    public void publishOrderCreated(Long orderId, String orderNo, String shortId,
                                   String platform, Long shopId, BigDecimal totalAmount,
                                   String paymentMethod, LocalDateTime orderTime) {
        try {
            OrderCreatedEvent event = new OrderCreatedEvent(
                    orderId, orderNo, shortId, platform, shopId,
                    totalAmount, paymentMethod, orderTime, "system");
            eventPublisher.publishEvent(event);
            log.info("[事件发布] OrderCreatedEvent: orderId={}, shortId={}", orderId, shortId);
        } catch (Exception e) {
            log.error("[事件发布失败] OrderCreatedEvent: orderId={}, error={}", orderId, e.getMessage(), e);
        }
    }

    /**
     * 发布订单支付成功事件
     */
    @Async
    public void publishOrderPaid(Long orderId, String orderNo, String shortId,
                                String platform, Long shopId, BigDecimal paidAmount,
                                String paymentMethod, LocalDateTime paymentTime) {
        try {
            OrderPaidEvent event = new OrderPaidEvent(
                    orderId, orderNo, shortId, platform, shopId,
                    paidAmount, paymentMethod, paymentTime);
            eventPublisher.publishEvent(event);
            log.info("[事件发布] OrderPaidEvent: orderId={}, shortId={}, amount={}",
                    orderId, shortId, paidAmount);
        } catch (Exception e) {
            log.error("[事件发布失败] OrderPaidEvent: orderId={}, error={}", orderId, e.getMessage(), e);
        }
    }

    /**
     * 发布订单发货事件 - 驱动财务记录应收
     */
    @Async
    public void publishOrderShipped(Long orderId, String orderNo, String shortId,
                                   String platform, Long shopId,
                                   String expressCompany, String expressNo,
                                   BigDecimal goodsAmount, BigDecimal freight,
                                   BigDecimal totalAmount, LocalDateTime shipTime) {
        try {
            OrderShippedEvent event = new OrderShippedEvent(
                    orderId, orderNo, shortId, platform, shopId,
                    expressCompany, expressNo, goodsAmount, freight,
                    totalAmount, shipTime);
            eventPublisher.publishEvent(event);
            log.info("[事件发布] OrderShippedEvent: orderId={}, shortId={}, express={}",
                    orderId, shortId, expressNo);
        } catch (Exception e) {
            log.error("[事件发布失败] OrderShippedEvent: orderId={}, error={}", orderId, e.getMessage(), e);
        }
    }

    /**
     * 发布订单取消/退款事件 - 驱动财务处理退款
     */
    @Async
    public void publishOrderCancelled(Long orderId, String orderNo, String shortId,
                                     String platform, Long shopId,
                                     BigDecimal refundAmount, String refundReason,
                                     String eventType, LocalDateTime eventTime) {
        try {
            OrderCancelledEvent event = new OrderCancelledEvent(
                    orderId, orderNo, shortId, platform, shopId,
                    refundAmount, refundReason, eventType, eventTime);
            eventPublisher.publishEvent(event);
            log.info("[事件发布] OrderCancelledEvent: orderId={}, shortId={}, type={}",
                    orderId, shortId, eventType);
        } catch (Exception e) {
            log.error("[事件发布失败] OrderCancelledEvent: orderId={}, error={}", orderId, e.getMessage(), e);
        }
    }
}
