import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import ErrorBoundary from './components/ErrorBoundary.tsx'
import './index.css'
import { initializeSystemTimezone } from './utils/timezone'

import { setupGlobalErrorHandlers } from './utils/errorLogger'
import { clearAllCaches, reloadWithCacheBust } from './utils/versionManager'
import { runManifestCheck } from './utils/manifestCheck'
import { reportWebVitals } from './utils/webVitals'

// Initialize system timezone from database
initializeSystemTimezone();

// Setup global error handlers to capture uncaught errors
setupGlobalErrorHandlers();

// Reload guard: prevent infinite reload loops on module import failures
const RELOAD_KEY = 'module_reload_attempt';
const RELOAD_MAX = 1; // Only one automatic reload per window to avoid loops
const RELOAD_TTL = 5 * 60 * 1000; // 5 minutes window

const getReloadCount = (): number => {
  try {
    const data = JSON.parse(sessionStorage.getItem(RELOAD_KEY) || '{}');
    if (Date.now() - (data.ts || 0) > RELOAD_TTL) return 0;
    return data.count || 0;
  } catch { return 0; }
};

const incrementReloadCount = () => {
  sessionStorage.setItem(RELOAD_KEY, JSON.stringify({ count: getReloadCount() + 1, ts: Date.now() }));
};

const unregisterAllServiceWorkers = async (): Promise<void> => {
  if (!('serviceWorker' in navigator)) return;
  try {
    const regs = await navigator.serviceWorker.getRegistrations();
    await Promise.all(regs.map((r) => r.unregister()));
  } catch {
    // ignore
  }
};

let moduleErrorHandled = false;

const handleModuleError = () => {
  // In-memory guard: only act once per page lifetime.
  if (moduleErrorHandled) return;
  moduleErrorHandled = true;

  const count = getReloadCount();
  if (count >= RELOAD_MAX) {
    // Already reloaded recently — do NOT loop. Show recovery UI.
    const root = document.getElementById('root');
    if (root && !root.innerHTML.trim()) {
      root.innerHTML = '<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;font-family:system-ui,sans-serif;gap:16px;padding:24px;text-align:center"><h2 style="margin:0;color:#333">Nueva versión disponible</h2><p style="margin:0;color:#666">Se detectó una actualización. Haz clic en el botón para cargar la nueva versión.</p><button id="bm-hard-refresh" style="padding:12px 24px;background:#10b981;color:white;border:none;border-radius:8px;font-size:16px;cursor:pointer">Actualizar ahora</button></div>';
      const btn = document.getElementById('bm-hard-refresh');
      btn?.addEventListener('click', async () => {
        try { sessionStorage.clear(); } catch { /* ignore */ }
        await unregisterAllServiceWorkers();
        await clearAllCaches();
        window.location.replace(window.location.origin);
      });
    }
    return;
  }

  incrementReloadCount();
  // Hard recovery: unregister SW + wipe Cache Storage, then cache-bust reload once.
  Promise.allSettled([unregisterAllServiceWorkers(), clearAllCaches()]).then(() => {
    reloadWithCacheBust();
  });
};

const isModuleError = (msg: string) =>
  msg.includes('Failed to fetch dynamically imported module') ||
  msg.includes('error loading dynamically imported module') ||
  msg.includes('Importing a module script failed');

// Handle module import errors gracefully
window.addEventListener('error', (event) => {
  if (event.message && isModuleError(event.message)) {
    handleModuleError();
  }
});

// Also handle unhandled promise rejections for dynamic imports
window.addEventListener('unhandledrejection', (event) => {
  const reason = event.reason?.message || event.reason?.toString() || '';
  if (isModuleError(reason)) {
    event.preventDefault();
    handleModuleError();
  }
});

const hostname = window.location.hostname;
const isPreviewRuntime =
  hostname.includes('id-preview--') ||
  hostname.includes('lovableproject.com') ||
  window.location.search.includes('__lovable_token=');
const isProductionBuild = import.meta.env.PROD;

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

  try {
    const registrations = await navigator.serviceWorker.getRegistrations();
    await Promise.all(registrations.map((registration) => registration.unregister()));
    await clearAllCaches();
  } catch (error) {
  }
};

if (isPreviewRuntime) {
  cleanupPreviewServiceWorkers();
}

// Register Service Worker only in real production, never in preview
if (isProductionBuild && !isPreviewRuntime && 'serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then((registration) => {
        if (registration.active) {
          registration.update().catch(() => {
            // Silently ignore update errors
          });
        }
      })
      .catch((error) => {
      });
  });
}

// Listen for notification click messages from service worker
if (isProductionBuild && !isPreviewRuntime && 'serviceWorker' in navigator) {
  navigator.serviceWorker.addEventListener('message', (event) => {
    if (event.data && event.data.type === 'NOTIFICATION_CLICK') {
      window.location.href = event.data.url;
    }
  });
}

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <ErrorBoundary>
      <App />
    </ErrorBoundary>
  </StrictMode>
);

// Verify the served manifest matches the one the PWA was installed with.
// Runs on every load (cheap), only triggers UI when standalone + mismatch.
runManifestCheck().catch(() => { /* ignore */ });

// Lightweight Web Vitals (LCP/CLS/INP/FCP) — dev-only or when ?vitals=1.
// Helps verify whether lazy-loading or layout changes regress LCP on
// Auth/Dashboard. Production calls are no-ops.
reportWebVitals();
