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

/**
 * 成本计算模块
 * 负责所有成本相关的计算
 */
export class CostCalculator {
  constructor(
    private order: BusinessAPI.OrderVO,
    private rules: OrderRules,
  ) {}

  /**
   * 计算总成本项
   * 包含所有符合条件的费用项目
   */
  calculateTotalCosts(): number {
    if (!this.order.orderCostList?.length) {
      return 0;
    }

    return this.order.orderCostList.reduce((total, cost) => {
      if (this.shouldIncludeCost(cost)) {
        const costAmount = DecimalUtils.multiply(
          cost.price || 0,
          cost.count || 0,
        );
        return DecimalUtils.add(total, costAmount);
      }
      return total;
    }, 0);
  }

  /**
   * 计算西瓜采购成本
   * 根据定价方式和重量计算
   */
  calculateMelonPurchaseCost(): number {
    return this.order.orderSupplierList.reduce((total, supplier) => {
      const weight = this.rules.getWeightBySupplierPricingMethod(supplier);
      const cost = DecimalUtils.multiply(weight, supplier.purchasePrice || 0);
      return DecimalUtils.add(total, cost);
    }, 0);
  }

  /**
   * 计算税费补贴
   */
  calculateTaxSubsidy(): number {
    if (!this.rules.shouldEnableCompanyRebate()) {
      return 0;
    }

    // 优先使用手动设置的税费补贴
    const manualTaxSubsidy = this.order.orderDealer?.taxSubsidy;
    if (manualTaxSubsidy !== undefined && manualTaxSubsidy !== null) {
      return manualTaxSubsidy;
    }

    // 计算默认税费补贴
    return this.calculateDefaultTaxSubsidy();
  }

  /**
   * 计算计提税金
   */
  calculateTaxProvision(): number {
    if (!this.rules.shouldEnableAccrualTax()) {
      return 0;
    }

    // 优先使用手动设置的计提税金
    const manualTaxProvision = this.order.orderDealer?.taxProvision;
    if (manualTaxProvision !== undefined && manualTaxProvision !== null) {
      return manualTaxProvision;
    }

    // 计算默认计提税金
    return this.calculateDefaultTaxProvision();
  }

  /**
   * 获取成本差异（调诚信志远分成）
   */
  getCostDifference(): number {
    return this.order.orderDealer?.costDifference || 0;
  }

  /**
   * 计算采购总成本（不包含运费）
   * = 西瓜采购成本 + 成本项 + 税费补贴 + 计提税金
   */
  calculateTotalPurchaseCost(withoutFreight = false): number {
    const melonCost = this.calculateMelonPurchaseCost();
    const otherCosts = this.calculateTotalCosts();
    const taxSubsidy = this.calculateTaxSubsidy();
    const taxProvision = this.calculateTaxProvision();
    const lossAmount = this.calculateLossAmount();

    let totalCost = DecimalUtils.add(
      melonCost,
      otherCosts,
      taxSubsidy,
      taxProvision,
      lossAmount,
    );

    if (this.rules.shouldIncludeFreightCost() && !withoutFreight) {
      totalCost = DecimalUtils.subtract(totalCost, this.getFreightCost() || 0);
    }

    return totalCost;
  }

  /**
   * 计算基础成本（西瓜采购成本 + 其他成本项）
   */
  calculateBaseCost(): number {
    const melonCost = this.calculateMelonPurchaseCost();
    const otherCosts = this.calculateTotalCosts();
    return DecimalUtils.add(melonCost, otherCosts);
  }

  /**
   * 计算完整成本（基础成本 + 成本差异）
   */
  calculateFullCost(): number {
    const baseCost = this.calculateBaseCost();
    const costDifference = this.getCostDifference();
    return DecimalUtils.add(baseCost, costDifference);
  }

  /**
   * 判断是否应该计入某个成本项
   */
  private shouldIncludeCost(cost: BusinessAPI.OrderCost): boolean {
    // 运费需要特殊判断
    if (
      (cost.name === "主运费" || cost.name === "短驳费") &&
      cost.type === "LOGISTICS_TYPE"
    ) {
      return this.rules.shouldIncludeFreightCost();
    }

    // 草帘费需要特殊判断
    if (cost.name === "草帘费" && cost.type === "LOGISTICS_TYPE") {
      return this.rules.shouldIncludeStrawCurtainCost();
    }

    // 付瓜农定金不需要计算
    if (cost.name === "付瓜农定金" && cost.type === "PRODUCTION_TYPE") {
      return false;
    }

    return true;
  }

  /**
   * 计算默认税费补贴
   * 公式：(销售金额 + 包装费) × 公司返利率 ÷ 100
   */
  private calculateDefaultTaxSubsidy(): number {
    const salesCalculator = new SalesCalculator(this.order, this.rules);
    const salesAmount = salesCalculator.calculateSalesAmount();
    const packagingCosts = this.calculateTotalCosts();
    const totalAmount = DecimalUtils.add(salesAmount, packagingCosts);
    const ratio = this.rules.getCompanyRebateRatio();

    return DecimalUtils.percentage(totalAmount, ratio);
  }

  /**
   * 计算默认计提税金
   * 公式：(市场报价 - 税费补贴) × 计提税率 ÷ 100
   */
  private calculateDefaultTaxProvision(): number {
    const salesCalculator = new SalesCalculator(this.order, this.rules);
    const marketPrice = salesCalculator.calculateMarketPrice();
    const taxSubsidy = this.calculateTaxSubsidy();
    const taxableAmount = DecimalUtils.subtract(marketPrice, taxSubsidy);
    const ratio = this.rules.getAccrualTaxRatio();

    return DecimalUtils.percentage(taxableAmount, ratio);
  }

  /**
   * 运费
   */
  getFreightCost(): number {
    return (
      this.order.orderCostList.find(
        (cost) =>
          cost.type === "LOGISTICS_TYPE" &&
          (cost.name === "主运费" || cost.name === "短驳费"),
      )?.price || 0
    );
  }

  /**
   * 获取定金金额（与押金相同，不同叫法）
   */
  getDepositAmount(): number {
    return this.order.orderSupplierList.reduce((total, supplier) => {
      if (!supplier.isDepositPaid) {
        return total;
      }
      return DecimalUtils.add(total, supplier.depositAmount || 0);
    }, 0);
  }

  /**
   * 草帘费
   */
  getStrawCurtainCost(): number {
    return (
      this.order.orderCostList.find(
        (cost) => cost.name === "草帘费" && cost.type === "LOGISTICS_TYPE",
      )?.price || 0
    );
  }

  /**
   * 计算亏损金额
   */
  calculateLossAmount(): number {
    if (!this.rules.shouldEnableLoss()) {
      return 0;
    }
    return this.order.orderDealer?.lossAmount || 0;
  }
}
