import process from "process";

interface RuntimeConfig {
  vsnGatewayApiUrl: string;
}

let cachedConfig: RuntimeConfig | null = null;
let configPromise: Promise<RuntimeConfig> | null = null;

export const getRuntimeConfig = async (): Promise<RuntimeConfig> => {
  // Return cached config immediately if available and valid
  if (cachedConfig && cachedConfig.vsnGatewayApiUrl) {
    return cachedConfig;
  }

  // Return existing promise if config is already being loaded
  if (configPromise) {
    return configPromise;
  }

  // Create new promise for loading config
  configPromise = (async () => {
    try {
      // Check if we're on server-side
      if (typeof window === 'undefined') {
        // Server-side: read file directly
        const fs = await import('fs/promises');
        const path = await import('path');
        const configPath = path.join(process.cwd(), 'public', 'runtime-config.json');
        const configData = await fs.readFile(configPath, 'utf-8');
        const parsedConfig = JSON.parse(configData);
        
        // Validate the config
        if (!parsedConfig.vsnGatewayApiUrl) {
          throw new Error('Invalid runtime config: vsnGatewayApiUrl is missing');
        }
        
        cachedConfig = parsedConfig;
        return cachedConfig!;
      } else {
        // Client-side: use fetch with no-cache to always get fresh config
        const response = await fetch('/runtime-config.json', { 
          cache: 'no-cache',
          headers: {
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Pragma': 'no-cache',
            'Expires': '0'
          }
        });
        
        if (!response.ok) {
          throw new Error(`Failed to fetch config: ${response.status}`);
        }
        
        const parsedConfig = await response.json();
        
        // Validate the config
        if (!parsedConfig.vsnGatewayApiUrl) {
          throw new Error('Invalid runtime config: vsnGatewayApiUrl is missing');
        }
        
        cachedConfig = parsedConfig;
        return cachedConfig!;
      }
    } catch (error) {
      console.error('Failed to load runtime config:', error);

      console.warn('Using fallback config from environment variable');
      const fallbackConfig: RuntimeConfig = {
        vsnGatewayApiUrl: process.env.NEXT_PUBLIC_VSN_GATEWAY_API_URL as string,
      };

      // Only cache fallback if it has a valid URL
      if (fallbackConfig.vsnGatewayApiUrl) {
        cachedConfig = fallbackConfig;
      }
      
      return fallbackConfig;
    } finally {
      configPromise = null;
    }
  })();

  return configPromise;
};

// Preload config immediately on client-side (browser)
if (typeof window !== 'undefined') {
  getRuntimeConfig().catch(console.error);
}

// Clear cache when needed
export const clearConfigCache = () => {
  cachedConfig = null;
  configPromise = null;
};