/**
 * ISO Currency Service
 * Manages ISO-4217 currency operations and XAU triangulation
 */

import { ethers } from 'ethers';

export interface CurrencyInfo {
  currencyCode: string;
  tokenAddress: string | null;
  xauRate: string;
  isActive: boolean;
  isTokenized: boolean;
}

export interface ExchangeRate {
  fromCurrency: string;
  toCurrency: string;
  rate: string;
  timestamp: number;
}

export class ISOCurrencyService {
  private provider: ethers.Provider;
  private isoCurrencyManager: ethers.Contract;

  constructor(provider: ethers.Provider, isoCurrencyManagerAddress: string) {
    this.provider = provider;
    
    this.isoCurrencyManager = new ethers.Contract(
      isoCurrencyManagerAddress,
      [], // ABI would go here
      provider
    );
  }

  /**
   * Get all supported currencies
   */
  async getSupportedCurrencies(): Promise<string[]> {
    try {
      return await this.isoCurrencyManager.getAllSupportedCurrencies();
    } catch (error) {
      console.error('Error getting supported currencies:', error);
      throw error;
    }
  }

  /**
   * Get exchange rate between two currencies
   */
  async getCurrencyRate(fromCurrency: string, toCurrency: string): Promise<ExchangeRate> {
    try {
      const rate = await this.isoCurrencyManager.getCurrencyRate(fromCurrency, toCurrency);
      
      return {
        fromCurrency,
        toCurrency,
        rate: rate.toString(),
        timestamp: Date.now(),
      };
    } catch (error) {
      console.error('Error getting currency rate:', error);
      throw error;
    }
  }

  /**
   * Convert amount via XAU triangulation
   */
  async convertViaXAU(
    fromCurrency: string,
    toCurrency: string,
    amount: string
  ): Promise<string> {
    try {
      const result = await this.isoCurrencyManager.convertViaXAU(
        fromCurrency,
        toCurrency,
        amount
      );
      return result.toString();
    } catch (error) {
      console.error('Error converting via XAU:', error);
      throw error;
    }
  }

  /**
   * Get currency information
   */
  async getCurrencyInfo(currencyCode: string): Promise<CurrencyInfo> {
    try {
      const info = await this.isoCurrencyManager.getCurrencyInfo(currencyCode);
      
      return {
        currencyCode,
        tokenAddress: info.tokenAddress === ethers.ZeroAddress ? null : info.tokenAddress,
        xauRate: info.xauRate.toString(),
        isActive: info.isActive,
        isTokenized: info.isTokenized,
      };
    } catch (error) {
      console.error('Error getting currency info:', error);
      throw error;
    }
  }

  /**
   * Get historical exchange rates
   */
  async getHistoricalRates(
    fromCurrency: string,
    toCurrency: string,
    startTime: number,
    endTime: number
  ): Promise<ExchangeRate[]> {
    // In production, this would query historical data from a database
    // For now, return current rate
    const currentRate = await this.getCurrencyRate(fromCurrency, toCurrency);
    return [currentRate];
  }

  /**
   * Register a new currency (admin only)
   */
  async registerCurrency(
    currencyCode: string,
    tokenAddress: string | null,
    xauRate: string,
    signer: ethers.Signer
  ): Promise<string> {
    try {
      const contractWithSigner = this.isoCurrencyManager.connect(signer);
      const tx = await contractWithSigner.registerCurrency(
        currencyCode,
        tokenAddress || ethers.ZeroAddress,
        xauRate
      );
      await tx.wait();
      return tx.hash;
    } catch (error) {
      console.error('Error registering currency:', error);
      throw error;
    }
  }
}

export default ISOCurrencyService;

