import React from "react";
import { createRoot } from "react-dom/client";
import { HelmetProvider } from "react-helmet-async";
import { registerSW } from "virtual:pwa-register";
import { initPwaInstall } from "./lib/pwaInstall";
import App from "./App.tsx";
import "./index.css";

// Recarga automática si un chunk dinámico quedó obsoleto tras un redeploy
// (los hashes de Vite cambian y el navegador pide un archivo que ya no existe).
const isChunkLoadError = (msg: string) =>
  /Failed to fetch dynamically imported module|Importing a module script failed|ChunkLoadError|Loading chunk [\d]+ failed/i.test(
    msg
  );

const handleChunkError = (msg: string) => {
  if (!isChunkLoadError(msg)) return;
  const key = "__chunk_reload_at";
  const last = Number(sessionStorage.getItem(key) || 0);
  if (Date.now() - last < 10_000) return; // evita bucles
  sessionStorage.setItem(key, String(Date.now()));
  window.location.reload();
};

const isHelmetError = (msg: string, stack?: string) =>
  /HelmetDispatcher|react-helmet-async/i.test(stack || "") ||
  /Cannot read properties of undefined \(reading 'add'\)/i.test(msg);

const logHelmetError = (source: string, err: unknown) => {
  const e = err as { message?: string; stack?: string; name?: string };
  const msg = e?.message || String(err);
  const stack = e?.stack;
  if (!isHelmetError(msg, stack)) return;
  // eslint-disable-next-line no-console
  console.error("[Helmet] Global error detected", {
    source,
    name: e?.name,
    message: msg,
    stack,
    url: window.location.href,
    hint: "Revisa el <Seo>/<Helmet> montado en esta ruta. El ErrorBoundary de Seo.tsx debería capturarlo con seoProps.",
  });
};

window.addEventListener("error", (e) => {
  handleChunkError(e.message || "");
  logHelmetError("window.error", e.error ?? { message: e.message });
});
window.addEventListener("unhandledrejection", (e) => {
  const reason = (e as PromiseRejectionEvent).reason;
  handleChunkError(String((reason as { message?: string })?.message || reason || ""));
  logHelmetError("unhandledrejection", reason);
});


// Service worker (PWA). En dev es un stub que no hace nada — ver devOptions
// en vite.config.ts. `autoUpdate` instala la versión nueva en segundo plano;
// el usuario la ve en la siguiente navegación completa, sin recarga forzada.
registerSW({ immediate: true });

// Debe engancharse antes de montar React: `beforeinstallprompt` se dispara una
// sola vez y muy pronto. Ver src/lib/pwaInstall.ts.
initPwaInstall();

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