import { useEffect, useState } from 'react';

/**
 * Trigger a re-render once web fonts have finished loading.
 *
 * Why
 * ───
 * `measureTextWidth` (used by the canvas-based text measurement utilities)
 * asks the browser for a rendered glyph width with a specific `font-family`.
 * Before the font's `.woff2` arrives over the network and is parsed, the
 * browser falls back to a system font and reports its width — almost
 * always wrong.
 *
 * On a fast connection that happens once at app start, before the user
 * notices. On a slow connection, or for fonts loaded via `@font-face`
 * with `font-display: swap`, the measurement can lag the eventual render
 * by several hundred milliseconds — long enough for arc-text paths and
 * bounds-violation flags to be computed against fallback metrics.
 *
 * The fix is to re-render once `document.fonts.ready` resolves, so any
 * `measureTextWidth` calls in render bodies retry with the now-loaded
 * fonts. This hook returns a boolean for components that want to
 * conditionally render a placeholder, but most callers can just call it
 * for the side effect (the hook subscription causes the re-render).
 *
 * Resolves once per app lifetime
 * ──────────────────────────────
 * `document.fonts.ready` resolves once and stays resolved. After that,
 * this hook does nothing — no listener overhead. If new fonts are loaded
 * dynamically later (e.g. user picks a font we have to fetch on demand),
 * the consuming component would need its own re-render trigger.
 */
export function useFontsReady() {
  const [ready, setReady] = useState(() => {
    if (typeof document === 'undefined' || !document.fonts) return true;
    return document.fonts.status === 'loaded';
  });

  useEffect(() => {
    if (ready) return;
    if (typeof document === 'undefined' || !document.fonts) return;
    let cancelled = false;
    document.fonts.ready.then(() => {
      if (!cancelled) setReady(true);
    });
    return () => { cancelled = true; };
  }, [ready]);

  return ready;
}
