import { createElement } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { registerSW } from 'virtual:pwa-register'
import { setupModuleErrorHandlers } from './lib/moduleErrorHandler'
import { initGlobalErrorTracker } from './lib/globalErrorTracker'

setupModuleErrorHandlers();

const isPreviewEnv = () => {
  const hostname = window.location.hostname;
  return hostname.includes('preview') || 
         hostname.includes('lovableproject') ||
         hostname.includes('-preview--') ||
         (hostname.includes('lovable.app') && !hostname.startsWith('integra-er'));
};

const SW_CLEANUP_KEY = 'sw_cleanup_done_v3';

const cleanupServiceWorkerOnce = async () => {
  const shouldCleanup = import.meta.env.DEV || isPreviewEnv();
  if (!shouldCleanup) return;
  if (sessionStorage.getItem(SW_CLEANUP_KEY) === '1') return;

  try {
    const hasSW = 'serviceWorker' in navigator;
    const regs = hasSW ? await navigator.serviceWorker.getRegistrations() : [];
    if (regs.length > 0) {
      await Promise.all(regs.map((r) => r.unregister()));
    }
    if ('caches' in window) {
      const names = await caches.keys();
      if (names.length > 0) {
        await Promise.all(names.map((n) => caches.delete(n)));
      }
    }
    sessionStorage.setItem(SW_CLEANUP_KEY, '1');
  } catch (e) {
    console.warn('[Boot] Erro durante limpeza:', e);
    sessionStorage.setItem(SW_CLEANUP_KEY, '1');
  }
};

const checkVersionAndUpdate = async () => {
  const REFRESH_KEY = 'version_refresh_done';
  if (sessionStorage.getItem(REFRESH_KEY) === '1') return true;
  if (isPreviewEnv()) return true;

  const emergencyRefresh = async (serverVersion?: string): Promise<boolean> => {
    try {
      if (serverVersion) localStorage.setItem('app_version', serverVersion);
      sessionStorage.setItem(REFRESH_KEY, '1');
      if ('serviceWorker' in navigator) {
        const regs = await navigator.serviceWorker.getRegistrations();
        await Promise.all(regs.map((r) => r.unregister()));
      }
      if ('caches' in window) {
        const names = await caches.keys();
        await Promise.all(names.map((name) => caches.delete(name)));
      }
      const nextUrl = new URL(window.location.href);
      nextUrl.searchParams.set('v', Date.now().toString());
      window.location.replace(nextUrl.toString());
      return true;
    } catch (e) {
      console.log('[App] Emergency refresh falhou:', e);
      return false;
    }
  };

  try {
    const res = await fetch('/version.json?t=' + Date.now(), {
      cache: 'no-store',
      headers: { 'Cache-Control': 'no-cache, no-store, must-revalidate' },
    });
    if (!res.ok) return true;
    const data = await res.json();
    const serverVersion: string | undefined = data?.version;
    const runningBuild = typeof __BUILD_ID__ !== 'undefined' ? __BUILD_ID__ : undefined;
    const isDevVersion = serverVersion === 'dev-local' || serverVersion === 'development';
    const localVersion = localStorage.getItem('app_version');

    if (isDevVersion) {
      if (!localVersion && serverVersion) localStorage.setItem('app_version', serverVersion);
      return true;
    }
    if (serverVersion && runningBuild && serverVersion !== runningBuild) {
      const didRefresh = await emergencyRefresh(serverVersion);
      if (didRefresh) return false;
    }
    if (localVersion && serverVersion && localVersion !== serverVersion) {
      const didRefresh = await emergencyRefresh(serverVersion);
      if (didRefresh) return false;
    }
    if (!localVersion && serverVersion) {
      localStorage.setItem('app_version', serverVersion);
    }
  } catch (e) {
    console.log('[App] Verificação de versão falhou:', e);
  }
  return true;
};

const renderApp = () => {
  const root = document.getElementById('root');
  if (!root) return;
  createRoot(root).render(createElement(App));
};

// Trabalho não crítico: corre depois do primeiro render para não bloquear a thread principal
const runDeferredBootTasks = async () => {
  try {
    initGlobalErrorTracker();
    await cleanupServiceWorkerOnce();
    await checkVersionAndUpdate();

    if (import.meta.env.PROD && !isPreviewEnv()) {
      try {
        const updateSW = registerSW({
          immediate: true,
          onNeedRefresh() { 
            try { updateSW(true); } catch (e) { console.warn('[SW] Refresh failed:', e); }
          },
          onOfflineReady() {},
          onRegisteredSW(_swUrl, r) {
            if (r) {
              setInterval(() => {
                try { r.update().catch(() => {}); } catch (e) { /* silent */ }
              }, 3_600_000);
            }
          },
          onRegisterError(error) {
            console.warn('[SW] Registration failed (non-critical):', error);
          },
        });
      } catch (e) {
        console.warn('[SW] Failed to register service worker:', e);
      }
    }
  } catch (error) {
    console.error('[Boot] Erro nas tarefas diferidas:', error);
  }
};

const scheduleDeferred = () => {
  const ric = (window as any).requestIdleCallback as
    | ((cb: () => void, opts?: { timeout: number }) => number)
    | undefined;
  if (ric) ric(() => { void runDeferredBootTasks(); }, { timeout: 3000 });
  else setTimeout(() => { void runDeferredBootTasks(); }, 1000);
};

const boot = () => {
  try {
    renderApp();
  } catch (error) {
    console.error('[Boot] Erro no arranque:', error);
  }
  scheduleDeferred();
};

boot();

