
import * as React from "react";
import { createRoot } from "react-dom/client";
import { HelmetProvider } from "react-helmet-async";
import "./index.css";
import "./i18n";
import { isChunkLoadError, reloadForFreshChunks } from "./lib/lazyWithRetry";

// Reload (time-guarded) on chunk load errors — stale files after a publish.
window.addEventListener('error', (e) => {
  if (isChunkLoadError(e.message || e.error)) reloadForFreshChunks();
});

window.addEventListener('unhandledrejection', (e) => {
  if (isChunkLoadError(e.reason)) reloadForFreshChunks();
});

// Load the app after error handlers are installed, including entry import errors.
const renderApp = async () => {
  try {
    const { default: App } = await import('./App.tsx');
    const container = document.getElementById("root");
    if (!container) {
      console.error("Root element not found");
      const showError = (window as any).showError;
      if (showError) showError("Root element not found. Please refresh the page.");
      return;
    }

    const hideLoader = (window as any).hideLoader;
    if (hideLoader) hideLoader();

    const root = createRoot(container);
    root.render(
      <React.StrictMode>
        <HelmetProvider>
          <App />
        </HelmetProvider>
      </React.StrictMode>
    );
  } catch (error) {
    console.error("Failed to render app:", error);
    const message = error instanceof Error ? error.message : String(error);
    if (isChunkLoadError(message) && reloadForFreshChunks()) return;
    const showError = (window as any).showError;
    if (showError) {
      showError("Failed to initialize app. Please refresh the page or try a different browser.");
    }
  }
};

renderApp();

// Register service worker so the app is installable as a PWA
// and persists on the user's device. We skip registration in:
//   - Lovable preview iframes (would interfere with hot reload)
//   - Non-production hostnames
const isInIframe = (() => {
  try { return window.self !== window.top; } catch { return true; }
})();
const host = window.location.hostname;
const isPreviewHost =
  host.includes('lovable.app') ||
  host.includes('lovableproject.com') ||
  host === 'localhost' ||
  host === '127.0.0.1';

if ('serviceWorker' in navigator && !isInIframe && !isPreviewHost) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/sw.js', { scope: '/', updateViaCache: 'none' })
      .then((reg) => {
        // Check for updates immediately and again periodically while the tab is open
        reg.update().catch(() => {});
        setInterval(() => reg.update().catch(() => {}), 60 * 1000);

        // When a new SW is waiting, activate it immediately so users get fresh content
        if (reg.waiting) reg.waiting.postMessage({ type: 'SKIP_WAITING' });
        reg.addEventListener('updatefound', () => {
          const newSW = reg.installing;
          if (!newSW) return;
          newSW.addEventListener('statechange', () => {
            if (newSW.state === 'installed' && navigator.serviceWorker.controller) {
              newSW.postMessage({ type: 'SKIP_WAITING' });
            }
          });
        });
      })
      .catch((err) => console.warn('SW registration failed:', err));

    // Re-check for updates whenever the user comes back to the tab
    document.addEventListener('visibilitychange', () => {
      if (document.visibilityState === 'visible') {
        navigator.serviceWorker.getRegistration().then((reg) => {
          reg?.update().catch(() => {});
        });
      }
    });

    // Reload once when a new SW takes control so the user sees the latest version
    let refreshing = false;
    navigator.serviceWorker.addEventListener('controllerchange', () => {
      if (refreshing || sessionStorage.getItem('sw_controller_reload')) return;
      refreshing = true;
      sessionStorage.setItem('sw_controller_reload', '1');
      window.location.reload();
    });

    // Also reload when the activated SW signals a new version (covers PWA installs
    // that already had the SW but needed the new bundle).
    navigator.serviceWorker.addEventListener('message', (event) => {
      if (event.data?.type === 'SW_ACTIVATED') {
        const lastVersion = sessionStorage.getItem('sw_version');
        if (lastVersion && lastVersion !== event.data.version) {
          sessionStorage.setItem('sw_version', event.data.version);
          window.location.reload();
        }
        sessionStorage.setItem('sw_version', event.data.version);
      }
    });
  });
}
