/* crabcc landing — in-browser playground.
   Live REPL against a REAL, smart-loaded crabcc index of facebook/react
   (v18.3.1). The index streams from the edge on idle; queries run locally.
   Exports to window. */
const { useState: useStateP, useRef: useRefP, useEffect: useEffectP } = React;

/* colorize a JS value as crabcc-terminal JSON (returns React nodes) */
function jsonNodes(value, indent = 0) {
  const pad = "  ".repeat(indent);
  const padIn = "  ".repeat(indent + 1);
  if (value === null) return [<span className="tk-dim">null</span>];
  if (typeof value === "number") return [<span className="tk-num">{String(value)}</span>];
  if (typeof value === "boolean") return [<span className="tk-num">{String(value)}</span>];
  if (typeof value === "string") return [<span className="tk-str">"{value}"</span>];
  if (Array.isArray(value)) {
    if (value.length === 0) return [<span className="tk-punc">[]</span>];
    const out = [<span className="tk-punc">[{"\n"}</span>];
    value.forEach((v, i) => {
      out.push(<span>{padIn}</span>, ...jsonNodes(v, indent + 1));
      out.push(<span className="tk-punc">{i < value.length - 1 ? "," : ""}{"\n"}</span>);
    });
    out.push(<span>{pad}</span>, <span className="tk-punc">]</span>);
    return out;
  }
  const keys = Object.keys(value);
  if (keys.length === 0) return [<span className="tk-punc">{"{}"}</span>];
  const out = [<span className="tk-punc">{"{"}{"\n"}</span>];
  keys.forEach((k, i) => {
    out.push(<span>{padIn}</span>, <span className="tk-key">"{k}"</span>, <span className="tk-punc">: </span>, ...jsonNodes(value[k], indent + 1));
    out.push(<span className="tk-punc">{i < keys.length - 1 ? "," : ""}{"\n"}</span>);
  });
  out.push(<span>{pad}</span>, <span className="tk-punc">{"}"}</span>);
  return out;
}

function Playground() {
  const CR = window.CRABCC;
  const [value, setValue] = useStateP("crabcc sym useState");
  const [history, setHistory] = useStateP([]);
  const [st, setSt] = useStateP(CR.status());
  const bodyRef = useRefP(null);
  const inputRef = useRefP(null);
  const didInit = useRefP(false);

  const runCmd = (raw) => {
    const cmd = (raw || value).trim();
    if (!cmd) return;
    const res = CR.run(cmd);
    if (res.pending) {
      setHistory((h) => [...h.slice(-6), { cmd, res: { ok: false, error: "index still loading…", loading: true } }]);
      CR.ready().then(() => setHistory((h) => h.map((e, i) => i === h.length - 1 && e.res.loading ? { cmd, res: CR.run(cmd) } : e)));
      return;
    }
    setHistory((h) => [...h.slice(-6), { cmd, res }]);
  };

  useEffectP(() => {
    const off = CR.onStatus(setSt);
    CR.load();
    CR.ready().then(() => {
      if (!didInit.current) { didInit.current = true; runCmd("crabcc sym useState"); }
    });
    return off;
  }, []);

  useEffectP(() => { if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight; }, [history]);

  const onKey = (e) => { if (e.key === "Enter") runCmd(); };
  const pick = (ex) => { setValue(ex); runCmd(ex); if (inputRef.current) inputRef.current.focus(); };

  const loading = st.state === "loading" || st.state === "idle";

  return (
    <section className="section" id="playground">
      <div className="wrap">
        <Head
          eyebrow="playground · live"
          title="Query the React source, right here"
          sub="The entire facebook/react v18.3.1 source — hooks, components, the scheduler — is indexed by crabcc and smart-loaded from the edge. Type a command (or tap an example) and it answers from the real symbol store, in your browser."
        />
        <div className="pg">
          <div className="pg__term">
            <div className="term__bar">
              <span className="term__dot term__dot--r"></span>
              <span className="term__dot term__dot--y"></span>
              <span className="term__dot term__dot--g"></span>
              <span className="term__title">
                crabcc — <span className="pwd">facebook/react@{st.ref || "v18.3.1"}</span>
                {" · "}{st.stats ? st.stats.symbols : "…"} symbols
              </span>
              <span className={"pg__load" + (loading ? " is-loading" : "")}>
                <span className="pg__load-dot"></span>
                {loading ? "streaming index…" : "indexed · " + st.ms + "ms"}
              </span>
            </div>
            <div className="pg__body" ref={bodyRef}>
              {history.length === 0 && (
                <div className="term__line"><span className="tk-dim">indexing facebook/react@v18.3.1 from the edge…</span></div>
              )}
              {history.map((h, i) => (
                <div className="pg__entry" key={i}>
                  <div className="term__line"><span className="tk-prompt">$ </span><span className="tk-cmd">{h.cmd.replace(/^\$\s*/, "")}</span></div>
                  {h.res.ok ? (
                    <>
                      <pre className="pg__json">{jsonNodes(h.res.result).map((n, j) => <React.Fragment key={j}>{n}</React.Fragment>)}</pre>
                      <div className="term__line"><span className="tk-dim">{Array.isArray(h.res.result) ? h.res.result.length + " result" + (h.res.result.length === 1 ? "" : "s") + " · " : ""}{h.res.meta.ms}ms · {h.res.meta.bytes} bytes</span></div>
                    </>
                  ) : (
                    <div className="term__line">{h.res.loading ? <span className="tk-dim">{h.res.error}</span> : <><span className="tk-err">error:</span> <span className="tk-dim">{h.res.error}</span></>}</div>
                  )}
                </div>
              ))}
            </div>
            <div className="pg__input">
              <span className="pg__prompt">$</span>
              <input ref={inputRef} className="pg__field" value={value} spellCheck={false} autoCapitalize="off" autoComplete="off" autoCorrect="off"
                onChange={(e) => setValue(e.target.value)} onKeyDown={onKey} aria-label="crabcc command" />
              <button className="pg__run" onClick={() => runCmd()}>run ↵</button>
            </div>
          </div>
          <div className="pg__side">
            <div className="pg__smart">
              <span className={"pg__smart-dot" + (loading ? " is-loading" : " is-ready")}></span>
              <div>
                <div className="pg__smart-h">{loading ? "smart-loading" : "index ready"}</div>
                <div className="pg__smart-s">{st.stats ? st.stats.symbols + " symbols · " + st.stats.files + " files · " + st.stats.edges + " edges" : "facebook/react"}</div>
              </div>
            </div>
            <div className="pg__side-h">try</div>
            <div className="pg__examples">
              {CR.examples.map((ex) => (
                <button className="pg__ex" key={ex} onClick={() => pick(ex)}>
                  <span className="tk-dim">$</span> {ex.replace(/^crabcc /, "")}
                </button>
              ))}
            </div>
            <p className="pg__note">120KB index served from the edge (R2 + Worker, cached), queried in your browser. supports <code>--count</code>, <code>--files-only</code>.</p>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Playground, jsonNodes });
