import "./lib/preSupabaseOAuthRedirectCapture";
import * as Sentry from '@sentry/react';
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import "./styles/public-animations.css";
import { toast } from "sonner";
import { warmGeoCache } from "./lib/clientGeo";
import { authDebug } from "./lib/authDebug";
import { hardResetClientStorage } from "./lib/hardResetClientStorage";
import { reportWebVitals } from "./lib/webVitals";

const sentryDsn = import.meta.env.VITE_SENTRY_DSN as string | undefined;
if (sentryDsn && import.meta.env.PROD) {
  Sentry.init({
    dsn: sentryDsn,
    tracesSampleRate: 0.1,
    environment: 'production',
    release: (import.meta.env.VITE_APP_VERSION as string | undefined) ?? 'unknown',
  });
}

// Recovery de emerg�ncia: /?reset=1 limpa TUDO (storage, IndexedDB, SW, caches)
// e redireciona para /auth. �til quando navegador mobile fica preso em loop.
if (typeof window !== "undefined") {
  const params = new URLSearchParams(window.location.search);
  if (params.get("reset") === "1") {
    void hardResetClientStorage({ reload: true, redirectTo: "/auth" });
  }
}

if (typeof window !== "undefined") {
  window.addEventListener("pb:auth-invalid-refresh", () => {
    toast.error("Sess�o expirada ou inv�lida. Entre novamente para continuar.");
  });

  window.addEventListener("error", (event) => {
    authDebug("window_error", { message: event.message, filename: event.filename, lineno: event.lineno });
  });

  window.addEventListener("unhandledrejection", (event) => {
    const message = String(event.reason?.message ?? event.reason ?? "unhandled_rejection");
    authDebug("window_unhandled_rejection", { message, path: window.location.pathname });
    // Para erros de chunk din�mico, N�O recarregamos automaticamente:
    // o reload tem o efeito colateral de re-disparar guards/redirect global,
    // o que estava jogando o usu�rio em /dashboard no iOS/Android ao clicar
    // em um item do menu. Em vez disso, apenas avisamos para o usu�rio tentar
    // de novo manualmente - o pr�ximo clique j� encontra o chunk no cache HTTP.
    if (/chunkloaderror|loading chunk|failed to fetch dynamically imported module|importing a module script failed/i.test(message)) {
      event.preventDefault?.();
      try {
        toast.error("N�o foi poss�vel carregar essa tela. Toque no menu novamente.");
      } catch {
        /* noop */
      }
    }
  });

  window.addEventListener("vite:preloadError", (event) => {
    authDebug("vite_preload_error", { path: window.location.pathname });
    // Idem acima: N�O recarrega - apenas pede pra tentar de novo.
    (event as Event).preventDefault?.();
  });
}

function scheduleNonCriticalWork(fn: () => void) {
  if (typeof requestIdleCallback === "function") {
    requestIdleCallback(() => fn(), { timeout: 4000 });
  } else {
    setTimeout(fn, 1);
  }
}

scheduleNonCriticalWork(() => warmGeoCache());
scheduleNonCriticalWork(() => reportWebVitals());

const isInIframe = (() => {
  try {
    return window.self !== window.top;
  } catch {
    return true;
  }
})();
const isPreviewHost =
  window.location.hostname.includes("id-preview--");

function registerServiceWorkerWhenIdle() {
  if (isPreviewHost || isInIframe) {
    navigator.serviceWorker?.getRegistrations().then((regs) => {
      regs.forEach((r) => r.unregister());
    });
    return;
  }
  if (!("serviceWorker" in navigator)) return;

  // Auto-reload (uma vez) quando um novo SW assume o controle, garantindo bundle fresco
  // ap�s deploys - evita o "Verificando..." preso por chunks antigos em cache.
  let didReload = false;
  navigator.serviceWorker.addEventListener("controllerchange", () => {
    if (didReload) return;
    didReload = true;
    window.location.reload();
  });

  const run = async () => {
    try {
      const reg = await navigator.serviceWorker.register("/sw.js", { updateViaCache: "none" });
      reg.active?.postMessage({ type: "CLEAR_OLD_CACHES" });
      // Quando uma nova vers�o � detectada, ativa imediatamente.
      reg.addEventListener("updatefound", () => {
        const sw = reg.installing;
        if (!sw) return;
        sw.addEventListener("statechange", () => {
          if (sw.state === "installed" && navigator.serviceWorker.controller) {
            sw.postMessage({ type: "SKIP_WAITING" });
          }
        });
      });
      // Checagem peri�dica de update (a cada 30 min em sess�es longas).
      setInterval(() => { reg.update().catch(() => {}); }, 30 * 60 * 1000);
    } catch {
      /* ignore */
    }
  };
  if (document.readyState === "complete") {
    scheduleNonCriticalWork(run);
  } else {
    window.addEventListener("load", () => scheduleNonCriticalWork(run), { once: true });
  }
}
registerServiceWorkerWhenIdle();

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