package com.ruoyi.web.modules.freight.support;

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

/**
 * 运费计算纯函数
 */
public final class FreightCalcSupport
{
    private FreightCalcSupport()
    {
    }

    public static BigDecimal calcByPiece(BigDecimal pieceCount, FreightCalcRule rule)
    {
        if (pieceCount == null || pieceCount.compareTo(BigDecimal.ZERO) <= 0)
        {
            return BigDecimal.ZERO;
        }
        if (rule == null || rule.getFirstUnit() == null || rule.getFirstFee() == null)
        {
            return BigDecimal.ZERO;
        }
        if (pieceCount.compareTo(rule.getFirstUnit()) <= 0)
        {
            return rule.getFirstFee();
        }
        BigDecimal extra = pieceCount.subtract(rule.getFirstUnit());
        BigDecimal addUnit = rule.getAddUnit();
        BigDecimal addFee = rule.getAddFee() == null ? BigDecimal.ZERO : rule.getAddFee();
        if (addUnit == null || addUnit.compareTo(BigDecimal.ZERO) <= 0)
        {
            return rule.getFirstFee();
        }
        int steps = extra.divide(addUnit, 0, RoundingMode.CEILING).intValue();
        return rule.getFirstFee().add(addFee.multiply(BigDecimal.valueOf(steps)));
    }

    public static BigDecimal calcByWeight(BigDecimal totalWeightKg, FreightCalcRule rule)
    {
        if (totalWeightKg == null || totalWeightKg.compareTo(BigDecimal.ZERO) <= 0)
        {
            return BigDecimal.ZERO;
        }
        if (rule == null || rule.getFirstUnit() == null || rule.getFirstFee() == null)
        {
            return BigDecimal.ZERO;
        }
        if (totalWeightKg.compareTo(rule.getFirstUnit()) <= 0)
        {
            return rule.getFirstFee();
        }
        BigDecimal extra = totalWeightKg.subtract(rule.getFirstUnit());
        BigDecimal addUnit = rule.getAddUnit();
        BigDecimal addFee = rule.getAddFee() == null ? BigDecimal.ZERO : rule.getAddFee();
        if (addUnit == null || addUnit.compareTo(BigDecimal.ZERO) <= 0)
        {
            return rule.getFirstFee();
        }
        int steps = extra.divide(addUnit, 0, RoundingMode.CEILING).intValue();
        return rule.getFirstFee().add(addFee.multiply(BigDecimal.valueOf(steps)));
    }

    public static boolean isFreeByThreshold(BigDecimal goodsAmount, BigDecimal freeThreshold)
    {
        return freeThreshold != null && freeThreshold.compareTo(BigDecimal.ZERO) > 0
                && goodsAmount != null && goodsAmount.compareTo(freeThreshold) >= 0;
    }

    public static String buildFreightDesc(boolean freeShipping, BigDecimal firstFee, BigDecimal freeThreshold)
    {
        if (freeShipping)
        {
            return "包邮";
        }
        StringBuilder sb = new StringBuilder();
        if (firstFee != null)
        {
            sb.append("运费 ¥").append(firstFee.setScale(2, RoundingMode.HALF_UP)).append(" 起");
        }
        if (freeThreshold != null && freeThreshold.compareTo(BigDecimal.ZERO) > 0)
        {
            if (sb.length() > 0)
            {
                sb.append("，");
            }
            sb.append("满 ¥").append(freeThreshold.setScale(2, RoundingMode.HALF_UP)).append(" 包邮");
        }
        return sb.length() == 0 ? null : sb.toString();
    }

    public static String buildFreightDesc(boolean freeShipping, BigDecimal firstFee, BigDecimal freeThreshold,
            BigDecimal goodsAmount)
    {
        if (freeShipping || isFreeByThreshold(goodsAmount, freeThreshold))
        {
            return "包邮";
        }
        return buildFreightDesc(false, firstFee, freeThreshold);
    }
}
