class MarginCalculator {
  /**
   * Calculate fee based on percentage, fixed fee, and caps.
   */
  static calculateFee(amount, percentage, fixedFee, minCap, maxCap) {
    const amt = parseFloat(amount || 0);
    const pct = parseFloat(percentage || 0);
    const fixed = parseFloat(fixedFee || 0);
    const min = parseFloat(minCap || 0);
    const max = parseFloat(maxCap || 999999999.99);

    let fee = (amt * pct) + fixed;

    // Apply Caps
    if (fee < min) fee = min;
    if (fee > max) fee = max;

    return fee;
  }

  /**
   * Calculates both provider and customer fees, and the resulting fee profit.
   */
  static calculatePricingMargin(amount, pricingConfig) {
    if (!pricingConfig) {
      return {
        providerFee: 0,
        customerFee: 0,
        profit: 0
      };
    }

    const providerFee = this.calculateFee(
      amount,
      pricingConfig.providerPercentage,
      pricingConfig.providerFixedFee,
      pricingConfig.providerMinCap,
      pricingConfig.providerMaxCap
    );

    const customerFee = this.calculateFee(
      amount,
      pricingConfig.customerPercentage,
      pricingConfig.customerFixedFee,
      pricingConfig.customerMinCap,
      pricingConfig.customerMaxCap
    );

    return {
      providerFee,
      customerFee,
      profit: Math.max(0, customerFee - providerFee) // Fee Profit
    };
  }

  /**
   * Converts currency and calculates the FX platform rate and margin profit.
   * 
   * @param {number} amount - The amount in target currency (e.g. 100 USD)
   * @param {object} exchangeRateConfig - The ExchangeRate database record
   * @param {number} liveRate - The live rate from the provider (e.g. NGN per USD, 1620)
   * @returns {object} { platformRate, convertedAmount, marginProfit }
   */
  static calculateFxMargin(amount, exchangeRateConfig, liveRate) {
    const amt = parseFloat(amount || 0);
    const live = parseFloat(liveRate || 0);

    if (!exchangeRateConfig) {
      return {
        platformRate: live,
        convertedAmount: amt * live,
        marginProfit: 0
      };
    }

    const configRate = parseFloat(exchangeRateConfig.rate || 0);
    const margin = parseFloat(exchangeRateConfig.margin || 0);
    const op = exchangeRateConfig.marginOperation; // 'add' or 'subtract'

    // Determine final platform rate
    // If a fixed rate is set in database (> 0), we use it. Otherwise, apply margin to live rate.
    let platformRate = configRate;
    if (configRate === 0) {
      platformRate = op === "add" ? live + margin : live - margin;
    }

    // Cost in base currency (e.g., NGN needed for USD payout)
    const convertedAmount = amt * platformRate;

    // FX Margin Profit (in base currency)
    // If op is 'add': we charge the user more than the live rate (platformRate > liveRate). Profit = amt * (platformRate - liveRate)
    // If op is 'subtract': we give the user less than the live rate (platformRate < liveRate). Profit = amt * (liveRate - platformRate)
    let marginProfit = 0;
    if (op === "add") {
      marginProfit = amt * (platformRate - live);
    } else if (op === "subtract") {
      marginProfit = amt * (live - platformRate);
    }

    return {
      platformRate,
      convertedAmount,
      marginProfit: Math.max(0, marginProfit)
    };
  }
}

export default MarginCalculator;
