import axios from 'axios';
import { ExchangeRate, ExchangeRateModel } from '../models/ExchangeRate';
import exchangeRateRepository from '../repositories/ExchangeRateRepository';
import currencyService from './CurrencyService';
import { logger } from '../utils/logger';

export class ExchangeRateService {
  private readonly exchangeRateApiKey: string;
  private readonly exchangeRateApiUrl: string;

  constructor() {
    this.exchangeRateApiKey = process.env.EXCHANGE_RATE_API_KEY || '';
    this.exchangeRateApiUrl = process.env.EXCHANGE_RATE_API_URL || 'https://api.exchangerate.host/latest';
  }

  async getExchangeRate(fromCurrency: string, toCurrency: string): Promise<ExchangeRate | null> {
    try {
      // 先从数据库查询
      const rate = await exchangeRateRepository.findByCurrencies(fromCurrency, toCurrency);
      if (rate) {
        logger.info(`[ExchangeRateService] Retrieved exchange rate from database: ${fromCurrency} to ${toCurrency}`);
        return rate;
      }

      // 如果数据库中没有，从API获取
      const apiRate = await this.fetchExchangeRateFromApi(fromCurrency, toCurrency);
      if (apiRate) {
        logger.info(`[ExchangeRateService] Retrieved exchange rate from API: ${fromCurrency} to ${toCurrency}`);
        return apiRate;
      }

      return null;
    } catch (error) {
      logger.error('[ExchangeRateService] Error getting exchange rate:', error);
      throw new Error('Failed to get exchange rate');
    }
  }

  async fetchExchangeRateFromApi(fromCurrency: string, toCurrency: string): Promise<ExchangeRate | null> {
    try {
      // 验证货币代码
      const fromCurrencyValid = await currencyService.validateCurrencyCode(fromCurrency);
      const toCurrencyValid = await currencyService.validateCurrencyCode(toCurrency);

      if (!fromCurrencyValid || !toCurrencyValid) {
        throw new Error('Invalid currency code');
      }

      // 调用汇率API
      const response = await axios.get(this.exchangeRateApiUrl, {
        params: {
          base: fromCurrency,
          symbols: toCurrency,
          access_key: this.exchangeRateApiKey,
        },
      });

      const rate = response.data.rates[toCurrency];
      if (!rate) {
        throw new Error('Rate not found');
      }

      const inverseRate = 1 / rate;

      // 创建汇率记录
      const rateData: Omit<ExchangeRate, 'id' | 'created_at' | 'updated_at'> = {
        from_currency: fromCurrency,
        to_currency: toCurrency,
        rate,
        inverse_rate: inverseRate,
        last_updated: new Date(),
        source: 'ExchangeRateHost API',
        created_by: 'system',
        updated_by: 'system',
      };

      // 保存到数据库
      const savedRate = await exchangeRateRepository.upsert(rateData);

      // 保存历史记录
      await this.saveExchangeRateHistory(fromCurrency, toCurrency, rate);

      return savedRate;
    } catch (error) {
      logger.error('[ExchangeRateService] Error fetching exchange rate from API:', error);
      throw new Error('Failed to fetch exchange rate from API');
    }
  }

  async updateExchangeRates(): Promise<number> {
    try {
      // 获取所有活跃货币
      const currencies = await currencyService.getCurrencies();
      const currencyCodes = currencies.map(c => c.code);

      let updatedCount = 0;

      // 更新所有货币对的汇率
      for (const fromCurrency of currencyCodes) {
        for (const toCurrency of currencyCodes) {
          if (fromCurrency !== toCurrency) {
            try {
              await this.fetchExchangeRateFromApi(fromCurrency, toCurrency);
              updatedCount++;
            } catch (error) {
              logger.warn(`[ExchangeRateService] Failed to update rate ${fromCurrency} to ${toCurrency}:`, error);
            }
          }
        }
      }

      logger.info(`[ExchangeRateService] Updated ${updatedCount} exchange rates`);
      return updatedCount;
    } catch (error) {
      logger.error('[ExchangeRateService] Error updating exchange rates:', error);
      throw new Error('Failed to update exchange rates');
    }
  }

  async saveExchangeRateHistory(fromCurrency: string, toCurrency: string, rate: number): Promise<void> {
    try {
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      // 检查今天是否已经有记录
      const exists = await exchangeRateRepository.existsHistory(fromCurrency, toCurrency, today);
      if (!exists) {
        const historyData = {
          from_currency: fromCurrency,
          to_currency: toCurrency,
          rate,
          date: today,
          source: 'ExchangeRateHost API',
          created_by: 'system',
        };

        await exchangeRateRepository.createHistory(historyData);
        logger.info(`[ExchangeRateService] Saved exchange rate history: ${fromCurrency} to ${toCurrency} on ${today.toISOString()}`);
      }
    } catch (error) {
      logger.error('[ExchangeRateService] Error saving exchange rate history:', error);
      // 历史记录保存失败不影响主流程
    }
  }

  async getExchangeRateHistory(fromCurrency: string, toCurrency: string, days: number = 30): Promise<any[]> {
    try {
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(startDate.getDate() - days);

      const history = await exchangeRateRepository.findHistoryByDateRange(
        fromCurrency,
        toCurrency,
        startDate,
        endDate
      );

      logger.info(`[ExchangeRateService] Retrieved ${history.length} exchange rate history records`);
      return history;
    } catch (error) {
      logger.error('[ExchangeRateService] Error getting exchange rate history:', error);
      throw new Error('Failed to get exchange rate history');
    }
  }

  async getAllExchangeRates(): Promise<ExchangeRate[]> {
    try {
      const rates = await exchangeRateRepository.findAll();
      logger.info(`[ExchangeRateService] Retrieved ${rates.length} exchange rates`);
      return rates;
    } catch (error) {
      logger.error('[ExchangeRateService] Error getting all exchange rates:', error);
      throw new Error('Failed to get all exchange rates');
    }
  }

  async calculateCrossRate(fromCurrency: string, toCurrency: string, viaCurrency: string = 'USD'): Promise<number | null> {
    try {
      // 计算交叉汇率: from -> via -> to
      const rate1 = await this.getExchangeRate(fromCurrency, viaCurrency);
      const rate2 = await this.getExchangeRate(viaCurrency, toCurrency);

      if (rate1 && rate2) {
        const crossRate = rate1.rate * rate2.rate;
        logger.info(`[ExchangeRateService] Calculated cross rate: ${fromCurrency} to ${toCurrency} via ${viaCurrency} = ${crossRate}`);
        return crossRate;
      }

      return null;
    } catch (error) {
      logger.error('[ExchangeRateService] Error calculating cross rate:', error);
      throw new Error('Failed to calculate cross rate');
    }
  }
}

export default new ExchangeRateService();
