import { DecimalUtils } from "../core/DecimalUtils";
import { OrderRules } from "../core/BusinessRules";

/**
 * 供应商计算模块
 * 负责单个供应商相关的计算
 */
export class OrderSupplierCalculator {
  constructor(
    private orderSupplier: BusinessAPI.OrderSupplier,
    private rules: OrderRules,
  ) {}

  /**
   * 获取毛重
   */
  getGrossWeight(): number {
    return this.orderSupplier.grossWeight || 0;
  }

  /**
   * 获取净重
   */
  getNetWeight(): number {
    return this.orderSupplier.netWeight || 0;
  }

  /**
   * 计算箱重
   * = 毛重 - 净重
   */
  getBoxWeight(): number {
    return DecimalUtils.subtract(this.getGrossWeight(), this.getNetWeight());
  }

  /**
   * 获取采购单价
   */
  getPurchasePrice(): number {
    return this.orderSupplier.purchasePrice || 0;
  }

  /**
   * 获取销售单价
   */
  getSalesPrice(): number {
    return this.orderSupplier.salePrice || 0;
  }

  /**
   * 根据定价方式获取重量
   */
  getWeightByOrderPricingMethod(): number {
    return this.rules.getWeightByOrderPricingMethod(this.orderSupplier);
  }

  /**
   * 根据定价方式获取重量
   */
  getWeightBySupplierPricingMethod(): number {
    return this.rules.getWeightBySupplierPricingMethod(this.orderSupplier);
  }

  /**
   * 计算采购金额
   * = 重量 × 采购单价
   */
  calculatePurchaseAmount(): number {
    const weight = this.getWeightBySupplierPricingMethod();
    const price = this.getPurchasePrice();
    return DecimalUtils.multiply(weight, price);
  }

  /**
   * 计算销售金额
   * = 重量 × 销售单价
   */
  calculateSalesAmount(): number {
    const weight = this.getWeightByOrderPricingMethod();
    const price = this.getSalesPrice();
    return DecimalUtils.multiply(weight, price);
  }

  /**
   * 计算采购合计金额（兼容旧逻辑）
   * 如果有使用中的纸箱，按净重计算；否则按毛重计算
   */
  getTotalAmount(): number {
    const hasUsedBoxes = this.hasUsedBoxes();
    const weight = hasUsedBoxes ? this.getNetWeight() : this.getGrossWeight();
    const price = this.getPurchasePrice();

    return DecimalUtils.multiply(weight, price);
  }

  /**
   * 计算毛利
   * = 销售金额 - 采购金额
   */
  calculateProfit(): number {
    const salesAmount = this.calculateSalesAmount();
    const purchaseAmount = this.calculatePurchaseAmount();
    return DecimalUtils.subtract(salesAmount, purchaseAmount);
  }

  /**
   * 获取已支付的押金金额
   */
  getDepositPaidAmount(): number {
    if (!this.orderSupplier.isDepositPaid) {
      return 0;
    }
    return this.orderSupplier.depositAmount || 0;
  }

  /**
   * 获取定金金额（与押金相同，不同叫法）
   */
  getDepositAmount(): number {
    return this.getDepositPaidAmount();
  }

  /**
   * 判断是否有使用中的纸箱
   */
  hasUsedBoxes(): boolean {
    return (
      this.orderSupplier.orderPackageList?.some(
        (pkg) => pkg.boxType === "USED",
      ) || false
    );
  }

  /**
   * 计算纸箱总重量
   * @param boxType 纸箱类型，不传则计算所有类型
   */
  calculateBoxesTotalWeight(boxType?: string): number {
    if (!this.orderSupplier.orderPackageList?.length) {
      return 0;
    }

    return this.orderSupplier.orderPackageList
      .filter((pkg) => !boxType || pkg.boxType === boxType)
      .reduce((total, pkg) => {
        const boxWeight = DecimalUtils.multiply(
          pkg.boxCount || 0,
          pkg.boxProductWeight || 0,
        );
        return DecimalUtils.add(total, boxWeight);
      }, 0);
  }

  /**
   * 计算使用中纸箱的数量
   */
  getUsedBoxCount(): number {
    if (!this.orderSupplier.orderPackageList?.length) {
      return 0;
    }

    return this.orderSupplier.orderPackageList
      .filter((pkg) => pkg.boxType === "USED")
      .reduce((total, pkg) => {
        return DecimalUtils.add(total, pkg.boxCount || 0);
      }, 0);
  }

  /**
   * 计算使用中纸箱的售卖金额
   */
  getUsedBoxesSaleAmount(): number {
    if (!this.orderSupplier.orderPackageList?.length) {
      return 0;
    }

    return this.orderSupplier.orderPackageList
      .filter((pkg) => pkg.boxType === "USED")
      .reduce((total, pkg) => {
        const saleAmount = DecimalUtils.multiply(
          pkg.boxCount || 0,
          pkg.boxSalePrice || 0,
        );
        return DecimalUtils.add(total, saleAmount);
      }, 0);
  }

  /**
   * 计算毛利率
   * = 毛利 ÷ 销售金额 × 100%
   */
  calculateProfitRate(): string {
    const profit = this.calculateProfit();
    const salesAmount = this.calculateSalesAmount();

    if (salesAmount === 0) {
      return "0.00";
    }

    const rate = DecimalUtils.percentage(profit, salesAmount);
    return DecimalUtils.toFixed(rate, 2);
  }

  /**
   * 计算斤价（按计价重量）
   */
  calculatePricePerJin(): string {
    const purchaseAmount = this.calculatePurchaseAmount();
    const weight = this.getWeightByOrderPricingMethod();

    if (weight === 0) {
      return "0.00";
    }

    const pricePerJin = DecimalUtils.divide(purchaseAmount, weight);
    return DecimalUtils.toFixed(pricePerJin, 2);
  }

  /**
   * 获取供应商名称
   */
  getSupplierName(): string {
    return this.orderSupplier.name || "";
  }

  /**
   * 判断供应商是否有效
   */
  isValid(): boolean {
    return !!this.orderSupplier.supplierId && !!this.orderSupplier.name;
  }
}
