/**
 * Global Configuration Cache Utility
 * Prevents repeated API calls and manages singleton pattern for configs
 * Designed to stop Safari iOS reload loops caused by repeated config fetches
 */

import type { RecaptchaConfig, RegistrationConfig } from './types';

// Global cache storage - use window object to persist across Vue reactivity cycles
interface ConfigCache {
  recaptcha: RecaptchaConfig | null;
  registration: RegistrationConfig | null;
  recaptchaLoading: boolean;
  registrationLoading: boolean;
  recaptchaError: string | null;
  registrationError: string | null;
}

// Use window object for true persistence across component lifecycle
function getGlobalCache(): ConfigCache {
  if (typeof window === 'undefined') {
    return {
      recaptcha: null,
      registration: null,
      recaptchaLoading: false,
      registrationLoading: false,
      recaptchaError: null,
      registrationError: null
    };
  }
  
  if (!(window as any).__configCache) {
    (window as any).__configCache = {
      recaptcha: null,
      registration: null,
      recaptchaLoading: false,
      registrationLoading: false,
      recaptchaError: null,
      registrationError: null
    };
  }
  
  return (window as any).__configCache;
}

// Circuit breaker to prevent rapid successive calls
const CIRCUIT_BREAKER_THRESHOLD = 5; // Max calls in time window
const CIRCUIT_BREAKER_WINDOW = 10000; // 10 seconds
const callHistory: { [key: string]: number[] } = {};

/**
 * Check if API calls should be blocked due to circuit breaker
 */
function shouldBlockCall(apiName: string): boolean {
  const now = Date.now();
  const history = callHistory[apiName] || [];
  
  // Clean old calls outside the time window
  const recentCalls = history.filter(time => now - time < CIRCUIT_BREAKER_WINDOW);
  callHistory[apiName] = recentCalls;
  
  if (recentCalls.length >= CIRCUIT_BREAKER_THRESHOLD) {
    console.warn(`[config-cache] Circuit breaker activated for ${apiName} - too many calls`);
    return true;
  }
  
  // Record this call
  recentCalls.push(now);
  return false;
}

/**
 * Get reCAPTCHA configuration with caching and circuit breaker
 */
export async function getCachedRecaptchaConfig(): Promise<RecaptchaConfig> {
  const globalConfigCache = getGlobalCache();
  
  // Return cached result if available
  if (globalConfigCache.recaptcha) {
    console.log('[config-cache] Returning cached reCAPTCHA config');
    return globalConfigCache.recaptcha;
  }

  // Check if already loading
  if (globalConfigCache.recaptchaLoading) {
    console.log('[config-cache] reCAPTCHA config already loading, waiting...');
    // Wait for loading to complete
    return new Promise((resolve, reject) => {
      const checkInterval = setInterval(() => {
        if (!globalConfigCache.recaptchaLoading) {
          clearInterval(checkInterval);
          if (globalConfigCache.recaptcha) {
            resolve(globalConfigCache.recaptcha);
          } else if (globalConfigCache.recaptchaError) {
            reject(new Error(globalConfigCache.recaptchaError));
          } else {
            reject(new Error('Unknown error loading reCAPTCHA config'));
          }
        }
      }, 100);
      
      // Timeout after 10 seconds
      setTimeout(() => {
        clearInterval(checkInterval);
        reject(new Error('Timeout waiting for reCAPTCHA config'));
      }, 10000);
    });
  }

  // Check circuit breaker
  if (shouldBlockCall('recaptcha-config')) {
    const fallbackConfig: RecaptchaConfig = { siteKey: '', secretKey: '' };
    globalConfigCache.recaptcha = fallbackConfig;
    return fallbackConfig;
  }

  try {
    console.log('[config-cache] Loading reCAPTCHA config...');
    globalConfigCache.recaptchaLoading = true;
    globalConfigCache.recaptchaError = null;

    const response = await $fetch('/api/recaptcha-config') as any;
    
    if (response?.success && response?.data) {
      globalConfigCache.recaptcha = response.data;
      console.log('[config-cache] reCAPTCHA config loaded successfully');
      return response.data;
    } else {
      throw new Error('Invalid reCAPTCHA config response');
    }
  } catch (error: any) {
    const errorMessage = error.message || 'Failed to load reCAPTCHA config';
    console.warn('[config-cache] reCAPTCHA config load failed:', errorMessage);
    globalConfigCache.recaptchaError = errorMessage;
    
    // Return fallback config instead of throwing
    const fallbackConfig: RecaptchaConfig = { siteKey: '', secretKey: '' };
    globalConfigCache.recaptcha = fallbackConfig;
    return fallbackConfig;
  } finally {
    globalConfigCache.recaptchaLoading = false;
  }
}

/**
 * Get registration configuration with caching and circuit breaker
 */
export async function getCachedRegistrationConfig(): Promise<RegistrationConfig> {
  const globalConfigCache = getGlobalCache();
  
  // Return cached result if available
  if (globalConfigCache.registration) {
    console.log('[config-cache] Returning cached registration config');
    return globalConfigCache.registration;
  }

  // Check if already loading
  if (globalConfigCache.registrationLoading) {
    console.log('[config-cache] Registration config already loading, waiting...');
    // Wait for loading to complete
    return new Promise((resolve, reject) => {
      const checkInterval = setInterval(() => {
        if (!globalConfigCache.registrationLoading) {
          clearInterval(checkInterval);
          if (globalConfigCache.registration) {
            resolve(globalConfigCache.registration);
          } else if (globalConfigCache.registrationError) {
            reject(new Error(globalConfigCache.registrationError));
          } else {
            reject(new Error('Unknown error loading registration config'));
          }
        }
      }, 100);
      
      // Timeout after 10 seconds
      setTimeout(() => {
        clearInterval(checkInterval);
        reject(new Error('Timeout waiting for registration config'));
      }, 10000);
    });
  }

  // Check circuit breaker
  if (shouldBlockCall('registration-config')) {
    const fallbackConfig: RegistrationConfig = {
      membershipFee: 150,
      iban: 'MC58 1756 9000 0104 0050 1001 860',
      accountHolder: 'ASSOCIATION MONACO USA'
    };
    globalConfigCache.registration = fallbackConfig;
    return fallbackConfig;
  }

  try {
    console.log('[config-cache] Loading registration config...');
    globalConfigCache.registrationLoading = true;
    globalConfigCache.registrationError = null;

    const response = await $fetch('/api/registration-config') as any;
    
    if (response?.success && response?.data) {
      globalConfigCache.registration = response.data;
      console.log('[config-cache] Registration config loaded successfully');
      return response.data;
    } else {
      throw new Error('Invalid registration config response');
    }
  } catch (error: any) {
    const errorMessage = error.message || 'Failed to load registration config';
    console.warn('[config-cache] Registration config load failed:', errorMessage);
    globalConfigCache.registrationError = errorMessage;
    
    // Return fallback config instead of throwing
    const fallbackConfig: RegistrationConfig = {
      membershipFee: 150,
      iban: 'MC58 1756 9000 0104 0050 1001 860',
      accountHolder: 'ASSOCIATION MONACO USA'
    };
    globalConfigCache.registration = fallbackConfig;
    return fallbackConfig;
  } finally {
    globalConfigCache.registrationLoading = false;
  }
}

/**
 * Load both configs with optimal batching
 * Useful for components that need both configs
 */
export async function loadAllConfigs(): Promise<{
  recaptcha: RecaptchaConfig;
  registration: RegistrationConfig;
}> {
  try {
    const [recaptcha, registration] = await Promise.allSettled([
      getCachedRecaptchaConfig(),
      getCachedRegistrationConfig()
    ]);

    return {
      recaptcha: recaptcha.status === 'fulfilled' 
        ? recaptcha.value 
        : { siteKey: '', secretKey: '' },
      registration: registration.status === 'fulfilled'
        ? registration.value 
        : {
            membershipFee: 150,
            iban: 'MC58 1756 9000 0104 0050 1001 860',
            accountHolder: 'ASSOCIATION MONACO USA'
          }
    };
  } catch (error) {
    console.error('[config-cache] Error loading configs:', error);
    // Return fallback configs
    return {
      recaptcha: { siteKey: '', secretKey: '' },
      registration: {
        membershipFee: 150,
        iban: 'MC58 1756 9000 0104 0050 1001 860',
        accountHolder: 'ASSOCIATION MONACO USA'
      }
    };
  }
}

/**
 * Clear all cached configurations (useful for testing or cache refresh)
 */
export function clearConfigCache(): void {
  console.log('[config-cache] Clearing all cached configurations');
  
  if (typeof window !== 'undefined' && (window as any).__configCache) {
    (window as any).__configCache = {
      recaptcha: null,
      registration: null,
      recaptchaLoading: false,
      registrationLoading: false,
      recaptchaError: null,
      registrationError: null
    };
  }
  
  // Clear call history for circuit breaker
  Object.keys(callHistory).forEach(key => {
    delete callHistory[key];
  });
}

/**
 * Get cache status for debugging
 */
export function getConfigCacheStatus(): ConfigCache {
  return { ...getGlobalCache() };
}

/**
 * Force reload specific config (bypasses cache)
 */
export async function reloadRecaptchaConfig(): Promise<RecaptchaConfig> {
  const globalConfigCache = getGlobalCache();
  globalConfigCache.recaptcha = null;
  globalConfigCache.recaptchaError = null;
  return getCachedRecaptchaConfig();
}

export async function reloadRegistrationConfig(): Promise<RegistrationConfig> {
  const globalConfigCache = getGlobalCache();
  globalConfigCache.registration = null;
  globalConfigCache.registrationError = null;
  return getCachedRegistrationConfig();
}
