import WeWireService from "../thirdParties/weWireService.js";
import GraphService from "../thirdParties/graphService.js";

class RateService {
  /**
   * Fetches the live exchange rate from the specified provider.
   * Rates are returned as baseCurrency per unit of targetCurrency (e.g. NGN per 1 USD).
   * 
   * @param {string} baseCurrency - e.g., 'NGN'
   * @param {string} targetCurrency - e.g., 'USD'
   * @param {string} source - 'manual', 'wewire', 'graph', 'nine_psb', etc.
   * @param {number} fallbackRate - The manual rate to use as a fallback
   * @returns {Promise<number>} The live exchange rate
   */
  static async getLiveRate(baseCurrency, targetCurrency, source = "manual", fallbackRate = 0) {
    try {
      switch (source) {
        case "wewire":
          return await this.fetchWeWireRate(baseCurrency, targetCurrency, fallbackRate);
        case "graph":
          return await this.fetchGraphRate(baseCurrency, targetCurrency, fallbackRate);
        case "nine_psb":
          return await this.fetchNinePsbRate(baseCurrency, targetCurrency, fallbackRate);
        case "manual":
        default:
          return parseFloat(fallbackRate || 0);
      }
    } catch (error) {
      console.error(`⚠️ Failed to fetch rate from source '${source}', using fallback:`, error.message);
      return parseFloat(fallbackRate || 0);
    }
  }

  /**
   * Fetch exchange rate from WeWire API.
   * WeWire returns pair rate as: targetCurrency per baseCurrency (e.g., USD per 1 NGN = 0.000617)
   * We need the inverse: baseCurrency per targetCurrency (e.g., NGN per 1 USD = 1620.50)
   */
  static async fetchWeWireRate(baseCurrency, targetCurrency, fallbackRate) {
    console.log(`[RateService] Fetching WeWire rate for ${baseCurrency} to ${targetCurrency}`);
    const response = await WeWireService.getPairRate(baseCurrency, targetCurrency);
    
    if (response && response.success && response.data) {
      // Use inverseRate if provided, otherwise compute it (1 / rate)
      if (response.data.inverseRate) {
        return parseFloat(response.data.inverseRate);
      }
      if (response.data.rate && response.data.rate > 0) {
        return 1 / parseFloat(response.data.rate);
      }
    }
    return parseFloat(fallbackRate || 0);
  }

  /**
   * Fetch exchange rate from Graph API.
   * Graph returns rates in format: { "USD_NGN": { "rate": 1615.00 } }
   */
  static async fetchGraphRate(baseCurrency, targetCurrency, fallbackRate) {
    console.log(`[RateService] Fetching Graph rate for ${baseCurrency} to ${targetCurrency}`);
    const response = await GraphService.getRates();
    
    if (response && response.status === "success" && response.data) {
      // e.g. key is 'USD_NGN'
      const key = `${targetCurrency}_${baseCurrency}`;
      if (response.data[key] && response.data[key].rate) {
        return parseFloat(response.data[key].rate);
      }
    }
    return parseFloat(fallbackRate || 0);
  }

  /**
   * Fetch exchange rate from 9PSB API.
   */
  static async fetchNinePsbRate(baseCurrency, targetCurrency, fallbackRate) {
    console.log(`[RateService] Fetching 9PSB rate for ${baseCurrency} to ${targetCurrency} (Fallback used)`);
    // 9PSB doesn't expose a public FX rate API, so we use fallback
    return parseFloat(fallbackRate || 0);
  }
}

export default RateService;
