import { useEffect, useState } from 'react';

/**
 * Dynamically remounts the Vite virtual live module when the harness changes.
 */
export function LivePreview() {
  const [revision, setRevision] = useState(0);
  const [Comp, setComp] = useState<React.ComponentType | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const onUpdate = () => setRevision((n) => n + 1);
    const handler = () => onUpdate();

    // Vite custom event from liveTsxPlugin
    if (import.meta.hot) {
      import.meta.hot.on('playground:live-updated', handler);
    }

    return () => {
      if (import.meta.hot) {
        import.meta.hot.off('playground:live-updated', handler);
      }
    };
  }, []);

  useEffect(() => {
    let cancelled = false;
    setError(null);
    setComp(null);

    import(/* @vite-ignore */ `/@playground/live.tsx?t=${revision}`)
      .then((mod) => {
        if (cancelled) return;
        const candidate = mod.default;
        if (typeof candidate !== 'function') {
          setError('Live module must `export default` a React component.');
          return;
        }
        setComp(() => candidate);
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        const message =
          err instanceof Error
            ? `${err.message}\n\n${err.stack ?? ''}`
            : String(err);
        setError(message);
      });

    return () => {
      cancelled = true;
    };
  }, [revision]);

  if (error) return <pre className="error-block">{error}</pre>;
  if (!Comp) return <div className="muted">Compiling harness…</div>;
  return <Comp />;
}
