import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3'

const STALE_ASSET_RECOVERY_KEY = 'cosmoquick_stale_asset_recovery_v3';

const getSafeSessionValue = (key: string): string | null => {
  try {
    return sessionStorage.getItem(key);
  } catch {
    return null;
  }
};

const setSafeSessionValue = (key: string, value: string) => {
  try {
    sessionStorage.setItem(key, value);
  } catch {
    // ignore storage access issues
  }
};

const clearCachesAndUnregisterSW = async () => {
  try {
    if ('caches' in window) {
      const cacheNames = await caches.keys();
      await Promise.all(cacheNames.map((name) => caches.delete(name)));
    }
    if ('serviceWorker' in navigator) {
      const regs = await navigator.serviceWorker.getRegistrations();
      await Promise.all(regs.map((r) => r.unregister()));
    }
  } catch {
    // ignore
  }
};

const registerServiceWorker = async () => {
  if (!('serviceWorker' in navigator)) return;

  try {
    const existing = await navigator.serviceWorker.getRegistration();
    if (!existing) {
      await navigator.serviceWorker.register('/sw.js', { scope: '/' });
    } else {
      await existing.update();
    }
    // REMOVED: controllerchange and SW_UPDATED reload listeners.
    // These were causing blank pages by reloading during chunk loads.
    // The SW now uses skipWaiting + claim without forcing client reload.
    // Users get fresh assets on their next navigation naturally.
  } catch (e) {
    console.log('Service worker registration/update failed:', e);
  }
};

// Delay SW registration so it doesn't compete with initial chunk loads
if (document.readyState === 'complete') {
  registerServiceWorker();
} else {
  window.addEventListener('load', () => {
    // Wait a bit after load to avoid competing with lazy imports
    setTimeout(registerServiceWorker, 2000);
  });
}

// Error boundary fallback for critical errors
const showErrorFallback = (error: Error) => {
  const root = document.getElementById('root');
  if (root) {
    root.innerHTML = `
      <div style="min-height: 100vh; display: flex; align-items: center; justify-content: center; background: #f8fafc; font-family: system-ui, -apple-system, sans-serif;">
        <div style="text-align: center; padding: 40px 32px; background: white; border-radius: 16px; box-shadow: 0 4px 24px rgba(0,0,0,0.08); max-width: 440px; margin: 20px;">
          <div style="width: 56px; height: 56px; background: #fef2f2; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 20px; font-size: 24px;">⚠️</div>
          <h1 style="color: #1e293b; margin: 0 0 8px; font-size: 20px; font-weight: 600;">Something went wrong</h1>
          <p style="color: #64748b; margin: 0 0 24px; font-size: 14px; line-height: 1.5;">We're experiencing a temporary issue. Please try refreshing the page.</p>
          <div style="display: flex; gap: 12px; justify-content: center;">
            <button onclick="window.location.reload()" style="background: #2563eb; color: white; border: none; padding: 10px 24px; border-radius: 8px; font-size: 14px; cursor: pointer; font-weight: 500;">
              Refresh Page
            </button>
            <button onclick="clearCacheAndReload()" style="background: transparent; color: #2563eb; border: 1px solid #2563eb; padding: 10px 24px; border-radius: 8px; font-size: 14px; cursor: pointer; font-weight: 500;">
              Clear Cache
            </button>
          </div>
          <p style="color: #94a3b8; font-size: 11px; margin-top: 20px; word-break: break-word;">Error: ${error.message || 'Unknown error'}</p>
        </div>
      </div>
    `;

    (window as any).clearCacheAndReload = async () => {
      try {
        await clearCachesAndUnregisterSW();
        localStorage.clear();
        sessionStorage.clear();
        window.location.reload();
      } catch {
        window.location.reload();
      }
    };
  }
};

const isStaleChunkError = (err: unknown) => {
  const msg =
    typeof err === 'string'
      ? err
      : (err as any)?.message || (err as any)?.reason?.message || String(err);
  return /Loading chunk|ChunkLoadError|Failed to fetch dynamically imported module|Importing a module script failed|Unable to preload CSS/i.test(
    msg
  );
};

const recoverFromStaleAssets = async () => {
  if (getSafeSessionValue(STALE_ASSET_RECOVERY_KEY) === 'true') return;
  setSafeSessionValue(STALE_ASSET_RECOVERY_KEY, 'true');
  await clearCachesAndUnregisterSW();
  window.location.reload();
};

// Wrap the app rendering in try-catch
try {
  const rootElement = document.getElementById('root');

  if (!rootElement) {
    throw new Error('Root element not found');
  }

  const root = createRoot(rootElement);

  root.render(
    <GoogleReCaptchaProvider
      reCaptchaKey="6LdtXsQrAAAAAFdF3meHzSzrQXuxK0XKLqtA8zYL"
      scriptProps={{ async: true, defer: true }}
    >
      <App />
    </GoogleReCaptchaProvider>
  );
} catch (error) {
  console.error('Failed to render app:', error);
  showErrorFallback(error as Error);
}

// Global error handler for unhandled errors
window.onerror = (message, source, lineno, colno, error) => {
  console.error('Global error:', { message, source, lineno, colno, error });

  if (isStaleChunkError(error || message)) {
    void recoverFromStaleAssets();
    return;
  }

  // Only show fallback if the root is completely empty (app didn't mount)
  if (document.getElementById('root')?.innerHTML === '') {
    showErrorFallback(error || new Error(String(message)));
  }
};

// Handle unhandled promise rejections
window.onunhandledrejection = (event) => {
  console.error('Unhandled promise rejection:', event.reason);

  if (isStaleChunkError(event.reason)) {
    void recoverFromStaleAssets();
  }
};
