import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

(globalThis as any).__COLLECTIV_DEV__ = import.meta.env.DEV;

declare global {
  interface Window {
    __collectivRemoveBootSplash?: () => void;
    __collectivRemoveStaticShell?: () => void;
    __collectivBootStage?: string;
    __collectivBootStartedAt?: number;
  }
}

const setBootStage = (stage: string) => {
  if (typeof window !== 'undefined') {
    window.__collectivBootStage = stage;
  }
};

setBootStage('main-script-running');

const CHUNK_ERROR_PATTERN =
  /Failed to fetch dynamically imported module|Importing a module script failed|Loading chunk \d+ failed|ChunkLoadError|error loading dynamically imported module/i;

const BOOT_RELOAD_COUNT_KEY = '__collectiv_boot_import_reload_count';
const BOOT_RELOAD_MAX = 1;

const isBootImportError = (err: unknown): boolean => {
  const message = err instanceof Error ? err.message : String(err ?? '');
  return CHUNK_ERROR_PATTERN.test(message);
};

const recordBootEvent = (event: string, meta?: Record<string, unknown>) => {
  if (typeof window === 'undefined') return;
  try {
    const raw = sessionStorage.getItem('__collectiv_boot_log');
    const entries = raw ? JSON.parse(raw) : [];
    entries.push({ t: Date.now(), event, meta });
    sessionStorage.setItem('__collectiv_boot_log', JSON.stringify(entries.slice(-50)));
  } catch {
    /* ignore */
  }
};

const getBootReloadCount = () => {
  try {
    return parseInt(sessionStorage.getItem(BOOT_RELOAD_COUNT_KEY) || '0', 10) || 0;
  } catch {
    return 0;
  }
};

const reloadBootImportOnce = (err: unknown): boolean => {
  if (typeof window === 'undefined' || !isBootImportError(err)) return false;
  const count = getBootReloadCount();
  if (count >= BOOT_RELOAD_MAX) return false;
  try {
    sessionStorage.setItem(BOOT_RELOAD_COUNT_KEY, String(count + 1));
  } catch {
    /* ignore */
  }
  const separator = window.location.search ? '&' : '?';
  window.location.href = `${window.location.pathname}${window.location.search}${separator}_boot_import=${Date.now()}${window.location.hash}`;
  return true;
};

const BootShell = () => (
  <div className="flex min-h-screen items-center justify-center bg-background text-foreground">
    <div className="flex items-center gap-3" aria-label="Chargement de Collectiv">
      <div className="flex h-8 w-8 items-center justify-center rounded-md bg-primary text-sm font-semibold text-primary-foreground">
        C
      </div>
      <div>
        <div className="text-lg font-semibold leading-tight">Collectiv</div>
        <div className="mt-1 text-sm text-muted-foreground">Chargement de votre espace…</div>
      </div>
    </div>
  </div>
);

const BootError = ({ error }: { error: unknown }) => {
  const message = error instanceof Error ? error.message : 'Le module applicatif principal n’a pas pu être chargé.';

  return (
    <div className="flex min-h-screen items-center justify-center bg-background p-6 text-center text-foreground">
      <div className="max-w-md rounded-lg border border-destructive/30 bg-destructive/5 p-6">
        <h1 className="text-xl font-semibold text-destructive">Chargement interrompu</h1>
        <p className="mt-3 text-sm text-muted-foreground">{message}</p>
        <button
          type="button"
          className="mt-5 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90"
          onClick={() => {
            try {
              sessionStorage.removeItem(BOOT_RELOAD_COUNT_KEY);
              sessionStorage.removeItem('__collectiv_chunk_reload_count');
              sessionStorage.removeItem('__collectiv_chunk_reload_last');
            } catch {
              /* ignore */
            }
            window.location.reload();
          }}
        >
          Recharger
        </button>
      </div>
    </div>
  );
};

const rootElement = document.getElementById('root');

if (!rootElement) {
  throw new Error('[Collectiv boot] #root introuvable');
}

let root: ReactDOM.Root;
try {
  root = ReactDOM.createRoot(rootElement);
  setBootStage('react-mounted');
} catch (err) {
  recordBootEvent('react_mount_failed', {
    message: err instanceof Error ? err.message : String(err),
  });
  throw err;
}

try {
  root.render(
    <React.StrictMode>
      <BootShell />
    </React.StrictMode>,
  );
  setBootStage('boot-shell-rendered');
  recordBootEvent('root_shell_rendered');
  // Le placeholder statique sera remplacé naturellement par React,
  // mais on signale explicitement qu'on a la main.
  window.__collectivRemoveStaticShell?.();
} catch (err) {
  recordBootEvent('boot_shell_render_failed', {
    message: err instanceof Error ? err.message : String(err),
  });
  // Sans BootShell on est foutu ; on laisse le placeholder HTML en place.
}

// 🛟 Vite dispatch `vite:preloadError` quand un chunk préloadé renvoie 404
// (cas typique post-rebuild Lovable). On mutualise le compteur de
// `lazyWithRetry` pour ne JAMAIS boucler silencieusement.
if (typeof window !== 'undefined') {
  window.addEventListener('vite:preloadError', (e: any) => {
    e.preventDefault();
    const payload = e?.payload?.url || e?.payload || 'unknown';
    recordBootEvent('preload_error', { payload: String(payload) });
    reloadBootImportOnce(e?.payload || new Error('vite:preloadError'));
  });
}

setBootStage('app-import-pending');

Promise.all([
  import('./App.tsx'),
  import('@/components/error/ErrorBoundary'),
])
  .then(([{ default: App }, { ErrorBoundary }]) => {
    try {
      sessionStorage.removeItem(BOOT_RELOAD_COUNT_KEY);
    } catch {
      /* ignore */
    }
    setBootStage('app-rendered');
    recordBootEvent('root_import_loaded');
    root.render(
      <React.StrictMode>
        <ErrorBoundary label="Root">
          <App />
        </ErrorBoundary>
      </React.StrictMode>,
    );
  })
  .catch((err) => {
    recordBootEvent('root_import_failed', {
      message: err instanceof Error ? err.message : String(err),
    });
    if (reloadBootImportOnce(err)) return;
    window.__collectivRemoveBootSplash?.();
    root.render(
      <React.StrictMode>
        <BootError error={err} />
      </React.StrictMode>,
    );
  });
