import { useEffect, useRef, useState, type ReactNode } from 'react';
import type { Config } from 'vega-lite';
import type { VisualizationSpec } from 'vega-embed';
import { prepareSpecForRender } from '@core/rendering';
import styles from './Landing.module.css';

/**
 * Renders a Vega-Lite spec into the page using the app's real `renderSpec`
 * service. The renderer (and the heavy Vega chunk it pulls) is imported
 * dynamically inside the effect, so the landing's initial bundle stays light and
 * Vega loads only once a chart actually needs to draw.
 *
 * `prepareSpecForRender` is a pure core function (no Vega), so it's a static
 * import; only the render service is deferred. The host node is a plain div that
 * Vega owns — React never gives it children — with any error shown as a sibling.
 */
export function LandingChart({
  spec,
  config,
  className,
}: {
  spec: Record<string, unknown>;
  config: Config;
  className?: string;
}): ReactNode {
  const hostRef = useRef<HTMLDivElement>(null);
  const [failed, setFailed] = useState(false);

  useEffect(() => {
    let cancelled = false;
    let handle: { destroy(): void } | null = null;
    void (async () => {
      try {
        const { renderSpec } = await import('../app/services/chart-renderer');
        const node = hostRef.current;
        if (cancelled || !node) return;
        // Width-responsive: the chart fills its host (a definite-width `.chartNode`)
        // and keeps a natural height — right for every landing surface (hero pane,
        // builder, theme gallery).
        const prepared: unknown = prepareSpecForRender(spec, { fitMode: 'width' });
        handle = await renderSpec(node, prepared as VisualizationSpec, config);
        if (cancelled) {
          handle.destroy();
          handle = null;
          return;
        }
        setFailed(false);
      } catch {
        // The landing's specs are known-good; a failure here means the renderer
        // couldn't load (e.g. offline mid-session). Show a quiet note rather than
        // a blank box — the page is marketing, not the app's fail-loud surface.
        if (!cancelled) setFailed(true);
      }
    })();
    return () => {
      cancelled = true;
      handle?.destroy();
      handle = null;
    };
  }, [spec, config]);

  return (
    <div className={className ?? styles.chartHost}>
      {/* Vega brands this node `.vega-embed` (display:inline-block), which
          shrink-wraps it and collapses width:"container"; an explicit width gives
          the responsive fit a definite box (see LivePreview.module.css). */}
      <div ref={hostRef} className={styles.chartNode} />
      {failed && <span className={styles.chartError}>Couldn't render this chart.</span>}
    </div>
  );
}
