package org.dromara.mall.trade.utils;

import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.mall.coupon.domain.vo.MallCouponVo;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 优惠券计算工具类
 * 用于计算优惠券的折扣金额
 *
 * @author pengles
 */
@Slf4j
public class CouponCalculator {

    /**
     * 计算优惠券的折扣金额（单位：分）
     *
     * @param coupon 优惠券信息
     * @param orderAmount 订单金额（单位：分）
     * @return 折扣金额（单位：分），如果订单金额不满足使用门槛，返回0
     */
    public static Long calculateDiscountAmount(MallCouponVo coupon, Long orderAmount) {
        if (coupon == null) {
            throw new ServiceException("优惠券信息不能为空");
        }
        if (orderAmount == null || orderAmount <= 0) {
            throw new ServiceException("订单金额必须大于0");
        }

        // 检查使用门槛
        Integer minAmount = coupon.getMinAmount();
        if (minAmount != null && minAmount > 0 && orderAmount < minAmount) {
            log.debug("订单金额{}不满足优惠券{}的使用门槛{}", orderAmount, coupon.getId(), minAmount);
            return 0L;
        }

        Integer type = coupon.getType();
        if (type == null) {
            throw new ServiceException("优惠券类型不能为空");
        }

        Long discountAmount = 0L;

        // 0-满减，1-折扣，2-现金
        if (type == 0 || type == 2) {
            // 满减券或现金券：直接使用 discountAmount
            Integer couponDiscountAmount = coupon.getDiscountAmount();
            if (couponDiscountAmount == null || couponDiscountAmount <= 0) {
                throw new ServiceException("优惠券优惠金额配置错误");
            }
            discountAmount = couponDiscountAmount.longValue();
            // 确保折扣金额不超过订单金额
            if (discountAmount > orderAmount) {
                discountAmount = orderAmount;
            }
        } else if (type == 1) {
            // 折扣券：使用 discountRate（百分比）
            BigDecimal discountRate = coupon.getDiscountRate();
            if (discountRate == null || discountRate.compareTo(BigDecimal.ZERO) <= 0) {
                throw new ServiceException("优惠券折扣率配置错误");
            }
            if (discountRate.compareTo(new BigDecimal("100")) > 0) {
                throw new ServiceException("折扣率不能大于100%");
            }
            // 计算折扣金额：订单金额 * (折扣率 / 100)
            BigDecimal orderAmountDecimal = new BigDecimal(orderAmount);
            BigDecimal discountAmountDecimal = orderAmountDecimal
                    .multiply(discountRate)
                    .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
            discountAmount = discountAmountDecimal.setScale(0, RoundingMode.HALF_UP).longValue();
            // 确保折扣金额不超过订单金额
            if (discountAmount > orderAmount) {
                discountAmount = orderAmount;
            }
        } else {
            throw new ServiceException("不支持的优惠券类型: " + type);
        }

        log.debug("优惠券{}计算折扣金额: 订单金额={}, 折扣金额={}", coupon.getId(), orderAmount, discountAmount);
        return discountAmount;
    }

    /**
     * 计算优惠券的折扣金额（单位：分）
     * 使用优惠券ID和订单金额，需要传入优惠券查询方法
     *
     * @param couponService 优惠券服务，用于查询优惠券信息
     * @param couponId 优惠券ID
     * @param orderAmount 订单金额（单位：分）
     * @return 折扣金额（单位：分），如果订单金额不满足使用门槛或优惠券不存在，返回0
     */
    public static Long calculateDiscountAmount(
            org.dromara.mall.coupon.service.MallCouponService couponService,
            Long couponId,
            Long orderAmount) {
        if (couponService == null) {
            throw new ServiceException("优惠券服务不能为空");
        }
        if (couponId == null) {
            throw new ServiceException("优惠券ID不能为空");
        }

        org.dromara.mall.coupon.domain.vo.MallCouponVo coupon = couponService.queryById(couponId);
        if (coupon == null) {
            log.warn("优惠券{}不存在", couponId);
            return 0L;
        }

        return calculateDiscountAmount(coupon, orderAmount);
    }

    /**
     * 验证优惠券是否可用
     *
     * @param coupon 优惠券信息
     * @param orderAmount 订单金额（单位：分）
     * @return true表示可用，false表示不可用
     */
    public static boolean isValidCoupon(MallCouponVo coupon, Long orderAmount) {
        if (coupon == null) {
            return false;
        }
        // 检查状态
        if (coupon.getStatus() != null && coupon.getStatus() != 0) {
            return false;
        }
        // 检查使用门槛
        Integer minAmount = coupon.getMinAmount();
        if (minAmount != null && minAmount > 0 && orderAmount < minAmount) {
            return false;
        }
        // 检查有效期（如果订单服务需要，可以添加时间校验）
        return true;
    }
}
