package com.jeesharp.business.modules.food.application.support;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.food.dto.FoodMealOrderRefundSuccessDTO;
import com.jeesharp.business.modules.food.entity.FoodMealOrder;
import com.jeesharp.business.modules.food.entity.FoodMealOrderItem;
import com.jeesharp.business.modules.food.service.FoodMealMenuItemService;
import com.jeesharp.business.modules.food.service.FoodMealMenuItemSpecService;
import com.jeesharp.business.modules.food.service.FoodMealOrderItemService;
import com.jeesharp.business.modules.food.service.FoodMealOrderService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 个人订餐退款成功后的业务收尾：关单并回滚菜品已售数量（供微信退款回调与补偿共用）。
 *
 * @author jeesharp
 * @since 2026-06-11
 */
@Component
@AllArgsConstructor
public class FoodPersonalMealRefundCoordinator {

    private static final String ORDER_TYPE_PERSONAL = "personal";
    private static final String ORDER_STATUS_REFUNDED = "refunded";
    private static final String ORDER_STATUS_REFUNDING = "refunding";
    private static final String ORDER_STATUS_PAID = "paid";
    private static final String PAY_STATUS_REFUNDED = "refunded";
    private static final BigDecimal ZERO = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);

    private final FoodMealOrderService foodMealOrderService;
    private final FoodMealOrderItemService foodMealOrderItemService;
    private final FoodMealMenuItemService foodMealMenuItemService;
    private final FoodMealMenuItemSpecService foodMealMenuItemSpecService;

    /**
     * 渠道退款 SUCCESS 后幂等关闭订单并回滚库存。
     */
    public void applyRefundSuccess(String orderId, String refundReason, BigDecimal refundAmount, LocalDateTime refundTime) {
        if (StrUtil.isBlank(orderId)) {
            return;
        }
        FoodMealOrder order = foodMealOrderService.get(orderId.trim());
        if (order == null || !ORDER_TYPE_PERSONAL.equals(order.getOrderType())) {
            return;
        }
        if (ORDER_STATUS_REFUNDED.equals(order.getOrderStatus()) || PAY_STATUS_REFUNDED.equals(order.getPayStatus())) {
            return;
        }
        if (!ORDER_STATUS_REFUNDING.equals(order.getOrderStatus()) && !ORDER_STATUS_PAID.equals(order.getOrderStatus())) {
            return;
        }
        List<FoodMealOrderItem> items = foodMealOrderItemService.listByOrderId(order.getId());
        foodMealMenuItemService.releaseSoldQuantity(items, order.getTenantCode());
        foodMealMenuItemSpecService.releaseSoldQuantity(items, order.getTenantCode());
        BigDecimal amount = refundAmount != null ? money(refundAmount) : money(order.getUserPayAmount());
        order.setOrderStatus(ORDER_STATUS_REFUNDED);
        order.setPayStatus(PAY_STATUS_REFUNDED);
        order.setRefundAmount(amount);
        order.setRefundTime(refundTime != null ? refundTime : LocalDateTime.now());
        if (order.getRefundApplyTime() == null) {
            order.setRefundApplyTime(order.getRefundTime());
        }
        if (StrUtil.isNotBlank(refundReason)) {
            order.setRefundReason(refundReason);
        }
        foodMealOrderService.updateOrder(order);
        foodMealOrderItemService.markRefunded(items, false);
    }

    /**
     * 兼容旧退款回调 DTO 形态。
     */
    public void applyRefundSuccess(FoodMealOrderRefundSuccessDTO dto) {
        if (dto == null) {
            return;
        }
        applyRefundSuccess(
                dto.getOrderId(),
                null,
                dto.getRefundAmount(),
                dto.getRefundTime());
    }

    private static BigDecimal money(BigDecimal value) {
        return value == null ? ZERO : value.setScale(2, RoundingMode.HALF_UP);
    }
}
