import { WeightCalculationService } from "@/utils";
import { DecimalUtils } from "@/utils/classes/calculators/core/DecimalUtils";
import { OrderRules } from "./core/BusinessRules";
import { CostCalculator } from "./modules/CostCalculator";
import { SalesCalculator } from "./modules/SalesCalculator";
import { ProfitCalculator } from "./modules/ProfitCalculator";
import { PackagingCalculator } from "./modules/PackagingCalculator";
import { OrderSupplierCalculator } from "./modules/OrderSupplierCalculator";
import { SupplierWeightCalculator } from "./modules/SupplierWeightCalculator";

/**
 * 采购订单计算器
 *
 * 重构后的计算器采用模块化设计，将不同类型的计算分离到专门的模块中：
 * - CostCalculator: 成本相关计算
 * - SalesCalculator: 销售相关计算
 * - ProfitCalculator: 利润相关计算
 * - PackagingCalculator: 包装相关计算
 * - BusinessRules: 业务规则验证
 *
 * 使用示例：
 * ```typescript
 * const calculator = new OrderCalculator(orderVO);
 * const totalCost = calculator.getTotalPurchaseCost();
 * const profit = calculator.getPersonalProfit();
 * ```
 */
export class OrderCalculator {
  private rules: OrderRules;
  private costCalculator: CostCalculator;
  private salesCalculator: SalesCalculator;
  private profitCalculator: ProfitCalculator;
  private packagingCalculator: PackagingCalculator;

  constructor(orderVO: BusinessAPI.OrderVO) {
    this.rules = new OrderRules(orderVO);
    this.costCalculator = new CostCalculator(orderVO, this.rules);
    this.salesCalculator = new SalesCalculator(orderVO, this.rules);
    this.profitCalculator = new ProfitCalculator(orderVO, this.rules);
    this.packagingCalculator = new PackagingCalculator(orderVO);
  }

  // ==================== 成本相关计算 ====================

  /**
   * 计算总成本项
   * 包含所有符合条件的费用项目
   */
  getTotalCostAmount(): number {
    return this.costCalculator.calculateTotalCosts();
  }

  /**
   * 计算西瓜采购成本
   * 根据定价方式（毛重/净重）× 采购单价
   */
  getSupplierPurchaseCost(): number {
    return this.costCalculator.calculateMelonPurchaseCost();
  }

  /**
   * 采购成本（不包含运费）
   * = 西瓜采购成本 + 成本项 + 税费补贴 + 计提税金 + 成本差异
   */
  getTotalPurchaseCost(): number {
    return this.costCalculator.calculateTotalPurchaseCost();
  }

  /**
   * 西瓜采购成本（别名，与 getSupplierPurchaseCost 相同）
   */
  getMelonPurchaseCost(): number {
    return this.getSupplierPurchaseCost();
  }

  /**
   * 西瓜成本1 = 西瓜采购成本 + 成本项总和
   */
  getMelonCost1(): number {
    return this.costCalculator.calculateBaseCost();
  }

  /**
   * 西瓜成本2 = 西瓜成本1 + 成本差异
   */
  getMelonCost2(): number {
    return this.costCalculator.calculateFullCost();
  }

  /**
   * 获取税费补贴
   */
  getTaxSubsidy(): number {
    return this.costCalculator.calculateTaxSubsidy();
  }

  /**
   * 获取计提税金
   */
  getTaxProvision(): number {
    return this.costCalculator.calculateTaxProvision();
  }

  /**
   * 获取成本差异
   */
  getCostDifference(): number {
    return this.costCalculator.getCostDifference();
  }

  // ==================== 销售相关计算 ====================

  /**
   * 计算销售金额
   * 各供应商根据定价方式计算的重量 × 销售单价之和
   */
  getSalesAmount(): number {
    return this.salesCalculator.calculateSalesAmount();
  }

  /**
   * 计算市场报价
   * = 销售金额 + (包装费，如果配置包含)
   */
  getMarketPrice(): number {
    return this.salesCalculator.calculateMarketPrice();
  }

  /**
   * 计算平均采购价（老板看的收购单价）
   */
  getAveragePurchasePrice(): number {
    return this.salesCalculator.calculateAveragePurchasePrice();
  }

  /**
   * 计算平均销售单价（老板看的市场报价）
   */
  getAverageSalesPrice(): number {
    return this.salesCalculator.calculateAverageSalesPrice();
  }

  /**
   * 计算单斤成本
   * = 基础成本 ÷ 总重量，保留2位小数
   */
  getSingleCost(): string {
    return this.salesCalculator.calculateCostPerJin();
  }

  /**
   * 计算总重量（根据定价方式）
   */
  getTotalWeight(): number {
    return this.salesCalculator.calculateTotalWeight();
  }

  /**
   * 计算总毛重
   */
  getTotalGrossWeight(): number {
    return this.salesCalculator.calculateTotalGrossWeight();
  }

  /**
   * 计算总净重
   */
  getTotalNetWeight(): number {
    return this.salesCalculator.calculateTotalNetWeight();
  }

  /**
   * 计算单个供应商的销售金额
   */
  calculateSupplierAmount(supplier: BusinessAPI.OrderSupplier): number {
    return this.salesCalculator.calculateSupplierSalesAmount(supplier);
  }

  // ==================== 利润相关计算 ====================

  /**
   * 计算西瓜毛利润
   * = 市场报价 - 基础成本
   */
  getMelonGrossProfit(): number {
    return this.profitCalculator.calculateMelonGrossProfit();
  }

  /**
   * 计算西瓜净利润
   * = 毛利润 - 个人返点
   */
  getMelonNetProfit(): number {
    return this.profitCalculator.calculateMelonNetProfit();
  }

  /**
   * 计算个人利润
   * = 净利润 - 利润 + 成本差异
   */
  getPersonalProfit(): number {
    return this.profitCalculator.calculatePersonalProfit();
  }

  /**
   * 计算分成后净利润
   */
  getNetProfit(): number {
    return this.profitCalculator.calculateNetProfit();
  }

  /**
   * 计算诚信志远利润
   */
  getShareProfitRatio(): number {
    return this.profitCalculator.calculateShareProfit();
  }

  /**
   * 计算诚信志远看到的利润
   */
  getShareProfit(): number {
    return this.profitCalculator.calculateShareProfitView();
  }

  /**
   * 获取个人返点
   */
  getPersonalRebate(): number {
    return this.profitCalculator.getPersonalRebate();
  }

  /**
   * 计算亏损金额
   */
  getLossAmount(): number {
    return this.costCalculator.calculateLossAmount();
  }

  // ==================== 包装相关计算 ====================

  /**
   * 获取纸箱售卖费
   */
  getBoxSale(): number {
    return this.packagingCalculator.calculateBoxSaleAmount();
  }

  // ==================== 供应商相关计算 ====================

  /**
   * 获取供应商计算器
   */
  getSupplierCalculator(
    supplier: BusinessAPI.OrderSupplier,
  ): OrderSupplierCalculator {
    return new OrderSupplierCalculator(supplier, this.rules);
  }

  /**
   * 获取所有供应商的计算器
   */
  getAllSupplierCalculators(): OrderSupplierCalculator[] {
    if (!this.rules.order.orderSupplierList?.length) {
      return [];
    }

    return this.rules.order.orderSupplierList.map(
      (supplier) => new OrderSupplierCalculator(supplier, this.rules),
    );
  }

  /**
   * 计算所有供应商的总采购金额
   */
  getTotalSupplierPurchaseAmount(): number {
    return this.getAllSupplierCalculators().reduce((total, calc) => {
      return total + calc.calculatePurchaseAmount();
    }, 0);
  }

  /**
   * 计算所有供应商的总销售金额
   */
  getTotalSupplierSalesAmount(): number {
    return this.getAllSupplierCalculators().reduce((total, calc) => {
      return total + calc.calculateSalesAmount();
    }, 0);
  }

  /**
   * 计算所有供应商的总毛利
   */
  getTotalSupplierProfit(): number {
    return this.getAllSupplierCalculators().reduce((total, calc) => {
      return total + calc.calculateProfit();
    }, 0);
  }

  /**
   * 获取总纸箱数量
   */
  getBoxCount(): number {
    return this.packagingCalculator.calculateTotalBoxCount();
  }

  /**
   * 获取总箱重
   */
  getBoxWeight(): number {
    return this.packagingCalculator.calculateTotalBoxWeight();
  }

  /**
   * 获取运费
   */
  getDeliveryFee(): number {
    return this.costCalculator.getFreightCost();
  }

  /**
   * 获取供应商定金
   */
  getDepositAmount(): number {
    return this.costCalculator.getDepositAmount();
  }

  /**
   * 获取供应商定金
   */
  getSupplierDepositAmount(supplier: BusinessAPI.OrderSupplier): number {
    return this.getSupplierCalculator(supplier).getDepositAmount();
  }

  // ==================== 工具方法 ====================

  /**
   * 获取业务规则验证器
   */
  getRules(): OrderRules {
    return this.rules;
  }

  /**
   * 获取成本计算器实例
   */
  getCostCalculator(): CostCalculator {
    return this.costCalculator;
  }

  /**
   * 获取销售计算器实例
   */
  getSalesCalculator(): SalesCalculator {
    return this.salesCalculator;
  }

  /**
   * 获取利润计算器实例
   */
  getProfitCalculator(): ProfitCalculator {
    return this.profitCalculator;
  }

  /**
   * 获取包装计算器实例
   */
  getPackagingCalculator(): PackagingCalculator {
    return this.packagingCalculator;
  }

  /**
   * 获取原始订单数据
   */
  getOrder(): BusinessAPI.OrderVO {
    return this.rules.order;
  }

  // ==================== 重量计算相关 ====================

  /**
   * 计算供应商重量
   * @returns 计算后的订单数据
   */
  calculateSupplierWeights(): BusinessAPI.OrderVO {
    if (!this.rules.order.orderSupplierList?.length) {
      return this.rules.order;
    }

    // 使用重量计算服务处理供应商重量
    this.rules.order.orderSupplierList =
      WeightCalculationService.calculateWeights(
        this.rules.order.orderSupplierList,
      );

    return this.rules.order;
  }

  /**
   * 获取重量计算器
   */
  getWeightCalculator(): SupplierWeightCalculator | null {
    if (!this.rules.order.orderSupplierList?.length) {
      return null;
    }

    return WeightCalculationService.createCalculator(
      this.rules.order.orderSupplierList,
    );
  }

  /**
   * 获取重量统计信息
   */
  getWeightStatistics() {
    if (!this.rules.order.orderSupplierList?.length) {
      return null;
    }

    return WeightCalculationService.getWeightStatistics(
      this.rules.order.orderSupplierList,
    );
  }

  /**
   * 验证重量计算结果
   */
  validateWeightCalculation(): { isValid: boolean; errors: string[] } | null {
    const calculator = this.getWeightCalculator();
    if (!calculator) {
      return null;
    }

    return calculator.validate();
  }

  // ==================== 返点相关计算 ====================

  /**
   * 计算返点金额
   * 根据返点计算方式计算返点金额
   * @param rebateData 返点数据
   * @returns 返点金额
   */
  calculateRebateAmount(rebateData?: BusinessAPI.OrderRebate): number {
    // 如果没有提供返点数据，使用订单中的返点数据
    const rebate = rebateData || this.rules.order.orderRebate;

    if (!rebate) {
      return 0;
    }

    // 按净重计算
    if (rebate.calcMethod === "NET_WEIGHT") {
      return DecimalUtils.multiply(
        rebate.netWeight || 0,
        rebate.unitPrice || 0,
      );
    }

    // 固定金额
    return DecimalUtils.toDecimalPlaces(rebate.amount || 0);
  }
}
