import { useEffect, useRef, useState, type CSSProperties } from 'react';

/**
 * Renders an HTML documentation fragment produced by the API (either a raw
 * markdown render or an AI-beautified page) and post-processes any
 * `<div class="mermaid"> … </div>` blocks into rendered SVG diagrams.
 *
 * The content comes from our own backend, so it is treated as trusted author
 * HTML and rendered with dangerouslySetInnerHTML. Mermaid is imported lazily
 * (and only configured once) so the large diagram library stays out of the
 * main bundle unless a page actually contains diagrams.
 */

interface DocHtmlProps {
  html: string;
  style?: CSSProperties;
  className?: string;
}

let diagCounter = 0;
type MermaidRunner = { render: (id: string, src: string) => Promise<{ svg: string }> };
let mermaidPromise: Promise<MermaidRunner> | null = null;

async function loadMermaid(): Promise<MermaidRunner> {
  if (!mermaidPromise) {
    mermaidPromise = import('mermaid').then((mod) => {
      const mermaid = mod.default;
      mermaid.initialize({
        startOnLoad: false,
        theme: 'dark',
        securityLevel: 'strict',
        fontFamily: 'var(--font-mono, ui-monospace, monospace)',
      });
      return mermaid as unknown as MermaidRunner;
    });
  }
  return mermaidPromise;
}

export function DocHtml({ html, style, className }: DocHtmlProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    const root = containerRef.current;
    if (!root) return;

    const blocks = Array.from(root.querySelectorAll<HTMLElement>('div.mermaid'));
    if (blocks.length === 0) return;

    let cancelled = false;
    setError(null);

    (async () => {
      let runner: MermaidRunner;
      try {
        runner = await loadMermaid();
      } catch (err) {
        if (!cancelled) setError(err instanceof Error ? err.message : 'Failed to load diagram library');
        return;
      }

      for (const block of blocks) {
        const source = block.textContent ?? '';
        if (!source.trim()) continue;
        const id = `mmd-${diagCounter++}`;
        try {
          const { svg } = await runner.render(id, source);
          if (cancelled) return;
          block.innerHTML = svg;
        } catch (err) {
          if (cancelled) return;
          const msg = err instanceof Error ? err.message : String(err);
          block.innerHTML = `<pre style="color:var(--red, #f87171)">Mermaid error: ${msg}</pre>`;
          setError(msg);
        }
      }
    })();

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

  return (
    <>
      {error && (
        <div
          className="mb-4 rounded-lg border border-red/25 bg-red/8 px-4 py-2 font-mono text-[0.75rem] text-red"
          role="alert"
        >
          One or more diagrams failed to render: {error}
        </div>
      )}
      <div
        ref={containerRef}
        className={['doc-prose', className].filter(Boolean).join(' ')}
        style={style}
        dangerouslySetInnerHTML={{ __html: html }}
      />
    </>
  );
}
