import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';

const CHUNK_ERROR_PATTERNS = [
  'Importing a module script failed',
  'Failed to fetch dynamically imported module',
  'Failed to load module script',
  'Loading chunk',
  'ChunkLoadError',
];

const isChunkLoadError = (message: string): boolean =>
  CHUNK_ERROR_PATTERNS.some((pattern) => message.includes(pattern));

const getErrorMessage = (reason: unknown): string => {
  if (typeof reason === 'string') return reason;
  if (reason && typeof reason === 'object') {
    const maybeError = reason as { message?: unknown };
    if (typeof maybeError.message === 'string') return maybeError.message;
  }
  return '';
};

const getEventMessage = (event: Event | ErrorEvent): string => {
  const errorEvent = event as ErrorEvent & {
    error?: unknown;
    reason?: unknown;
    target?: EventTarget | null;
    filename?: string;
  };

  return [
    typeof errorEvent.message === 'string' ? errorEvent.message : '',
    getErrorMessage(errorEvent.error),
    getErrorMessage(errorEvent.reason),
    typeof errorEvent.filename === 'string' ? errorEvent.filename : '',
    errorEvent.target instanceof HTMLScriptElement ? errorEvent.target.src : '',
  ]
    .filter(Boolean)
    .join(' | ');
};

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

const clearAllCaches = async () => {
  if (!('caches' in window)) return;
  try {
    const keys = await caches.keys();
    await Promise.all(keys.map((key) => caches.delete(key)));
  } catch {
    // ignore
  }
};

const forceCacheBustingReload = () => {
  const guardKey = 'chunk-load-reload-ts';
  const now = Date.now();
  const lastReload = Number(sessionStorage.getItem(guardKey) || '0');

  // Prevent reload loops
  if (now - lastReload < 10000) return;
  sessionStorage.setItem(guardKey, String(now));

  const reload = () => {
    const url = new URL(window.location.href);
    url.searchParams.set('__reload', String(now));
    window.location.replace(url.toString());
  };

  // Clear SW + CacheStorage to recover from stale chunks
  Promise.all([clearServiceWorkers(), clearAllCaches()])
    .catch(() => undefined)
    .finally(reload);
};

if (typeof window !== 'undefined') {
  window.addEventListener('error', (event) => {
    const message = getEventMessage(event);
    if (!isChunkLoadError(message)) return;
    event.preventDefault();
    forceCacheBustingReload();
  }, true);

  window.addEventListener('unhandledrejection', (event) => {
    const message = getErrorMessage(event.reason);
    if (!isChunkLoadError(message)) return;
    event.preventDefault();
    forceCacheBustingReload();
  });

  window.addEventListener('vite:preloadError', (event) => {
    event.preventDefault();
    forceCacheBustingReload();
  });
}

const root = createRoot(document.getElementById('root')!);

// Render React app
root.render(<App />);
const revealApp = () => {
  document.documentElement.classList.add('app-ready');
};

if (document.readyState === 'complete') {
  requestAnimationFrame(revealApp);
} else {
  window.addEventListener('load', () => requestAnimationFrame(revealApp), { once: true });
  setTimeout(revealApp, 1200);
}

// Register Service Worker ONLY for real production builds (avoid preview/dev chunk cache issues)
const hostname = window.location.hostname;
const isLovablePreview = hostname.includes('lovableproject.com') || hostname.startsWith('id-preview--');

const shouldEnableSW =
  import.meta.env.PROD &&
  !isLovablePreview &&
  (hostname === 'sanpiti.com' || hostname === 'www.sanpiti.com' || hostname.endsWith('.lovable.app'));

if ('serviceWorker' in navigator && shouldEnableSW) {
  const registerSW = async () => {
    try {
      const registration = await navigator.serviceWorker.register('/sw.js', {
        scope: '/',
        updateViaCache: 'none',
      });

      setInterval(() => {
        registration.update();
      }, 5 * 60 * 1000);

      registration.addEventListener('updatefound', () => {
        const newWorker = registration.installing;
        if (newWorker) {
          newWorker.addEventListener('statechange', () => {
            if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
              newWorker.postMessage('skipWaiting');
            }
          });
        }
      });

      console.log('[App] Service Worker registered successfully');
    } catch (error) {
      console.warn('[App] Service Worker registration failed:', error);
    }
  };

  if ('requestIdleCallback' in window) {
    window.requestIdleCallback(registerSW, { timeout: 8000 });
  } else {
    setTimeout(registerSW, 4000);
  }
} else if ('serviceWorker' in navigator) {
  // Unregister any existing SW in dev/preview to prevent stale cache issues
  clearServiceWorkers();
  console.log('[App] Service Worker disabled in dev/preview mode');
}

