/**
 * Exchange rate utility functions
 */

import type { Env, ExchangeRateCache } from '../types';

/**
 * Exchange rate constants
 */
const EXCHANGE_RATE_CACHE_KEY = 'exchange_rate:USD_KRW';
const EXCHANGE_RATE_TTL_SECONDS = 3600; // 1 hour
export const EXCHANGE_RATE_FALLBACK = 1450; // Fallback KRW rate if API fails

/**
 * Get USD to KRW exchange rate with KV caching
 * Uses open.er-api.com free API
 */
export async function getExchangeRate(env: Env): Promise<number> {
  // Try to get cached rate from KV
  if (env.CACHE) {
    try {
      const cached = await env.CACHE.get(EXCHANGE_RATE_CACHE_KEY);
      if (cached) {
        const data = JSON.parse(cached) as ExchangeRateCache;
        console.log(`[ExchangeRate] Using cached rate: ${data.rate}`);
        return data.rate;
      }
    } catch (error) {
      console.warn('[ExchangeRate] Cache read error:', error);
    }
  }

  // Fetch fresh rate from API
  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout

    const response = await fetch('https://open.er-api.com/v6/latest/USD', {
      headers: { 'Accept': 'application/json' },
      signal: controller.signal,
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
      throw new Error(`API returned ${response.status}`);
    }

    const data = await response.json() as { rates?: { KRW?: number } };
    const rate = data?.rates?.KRW;

    if (!rate || typeof rate !== 'number' || rate < 1000 || rate > 2000) {
      console.warn('[ExchangeRate] Invalid rate from API:', rate);
      return EXCHANGE_RATE_FALLBACK;
    }

    console.log(`[ExchangeRate] Fetched fresh rate: ${rate}`);

    // Cache the rate
    if (env.CACHE) {
      try {
        const cacheData: ExchangeRateCache = {
          rate,
          timestamp: Date.now(),
        };
        await env.CACHE.put(EXCHANGE_RATE_CACHE_KEY, JSON.stringify(cacheData), {
          expirationTtl: EXCHANGE_RATE_TTL_SECONDS,
        });
      } catch (error) {
        console.warn('[ExchangeRate] Cache write error:', error);
      }
    }

    return rate;
  } catch (error) {
    if (error instanceof Error && error.name === 'AbortError') {
      console.warn('[ExchangeRate] Request timed out, using fallback');
    } else {
      console.error('[ExchangeRate] API error:', error);
    }
    return EXCHANGE_RATE_FALLBACK;
  }
}
