// Math.jsx — tiny React wrapper that auto-typesets its children via MathJax.
// Exposed as window.TeX (not Math — would shadow the JS Math builtin!).
//
// Usage (browser-Babel, window-globals, no imports):
//   <TeX>{anchor.statement}</TeX>
//   <TeX as="div" className="question-body">{cur.derivation}</TeX>
//
// Why: statements from the backend / PSETs may contain $…$ or $$…$$ delimiters.
// MathJax is loaded in index.html with startup.typeset:false, so unless some
// component explicitly calls typesetPromise after render, equations stay as
// raw source. This component does that call, keyed on the stringified
// content so re-renders with new math re-typeset cleanly.

function TeX({ children, as = "span", className, style, ...rest }) {
  const ref = React.useRef(null);
  const Tag = as;
  const content = React.Children.toArray(children).join("");

  React.useEffect(() => {
    let cancelled = false;
    const el = ref.current;
    if (!el) return;

    // MathJax v3 loads async via CDN. `window.MathJax` exists early (pre-config
    // object in index.html), but typesetPromise doesn't exist until the engine
    // finishes booting. Poll until the function is present, then run startup.
    const tryTypeset = () => {
      if (cancelled) return;
      const mj = window.MathJax;
      const fn = mj && (mj.typesetPromise || mj.typeset);
      if (!fn) {
        setTimeout(tryTypeset, 120);
        return;
      }
      const ready = mj.startup?.promise || Promise.resolve();
      ready.then(() => {
        if (cancelled) return;
        if (typeof mj.typesetPromise === "function") {
          mj.typesetPromise([el]).catch(() => {});
        } else if (typeof mj.typeset === "function") {
          try { mj.typeset([el]); } catch (e) { /* noop */ }
        }
      });
    };
    tryTypeset();
    return () => { cancelled = true; };
  }, [content]);

  return <Tag ref={ref} className={className} style={style} {...rest}>{children}</Tag>;
}

// Helper for imperative typesetting of an existing DOM node.
function typesetMath(el) {
  if (!el || !window.MathJax) return;
  const mj = window.MathJax;
  if (typeof mj.typesetPromise === "function") {
    mj.typesetPromise([el]).catch(() => {});
  } else if (typeof mj.typeset === "function") {
    try { mj.typeset([el]); } catch (e) { /* noop */ }
  }
}

Object.assign(window, { TeX, typesetMath });
