/* EYE B — "From a tutorial": YouTube → procedure → laid-out node graph */

// node graph layout (tidy columns, not spaghetti)
const NODES = [
  { id: "src",   x: 40,  y: 120, label: "video_source", kind: "input", val: "12:04" },
  { id: "trans", x: 40,  y: 215, label: "transcript",   kind: "input", val: "7 steps" },
  { id: "geo",   x: 250, y: 70,  label: "base_geo",     kind: "op",    val: "icosphere" },
  { id: "noise", x: 250, y: 170, label: "displace",     kind: "op",    val: "noise · 0.4" },
  { id: "mat",   x: 250, y: 270, label: "material",     kind: "op",    val: "subsurface" },
  { id: "light", x: 460, y: 130, label: "lighting",     kind: "op",    val: "3-point" },
  { id: "out",   x: 460, y: 240, label: "render_out",   kind: "output",val: "beauty" },
];
const EDGES = [
  ["src", "geo"], ["trans", "geo"], ["trans", "noise"], ["geo", "noise"],
  ["noise", "mat"], ["mat", "light"], ["mat", "out"], ["light", "out"],
];
const NODE_W = 150, NODE_H = 52;

function EyeB() {
  const [ref, shown] = useReveal();
  const [stage, setStage] = React.useState("idle"); // idle | learning | done
  const { lines, running, run, clear } = useStream();
  const feedRef = React.useRef(null);
  const [wired, setWired] = React.useState(0); // how many nodes have appeared

  React.useEffect(() => { if (feedRef.current) feedRef.current.scrollTop = feedRef.current.scrollHeight; }, [lines]);

  const SCRIPT = [
    { arrow: "→", text: "pulling transcript · ", em: "“Procedural Planet in Blender”" },
    { arrow: "→", text: "segmenting timeline into operations…" },
    { arrow: "→", text: "extracting procedure: ", wire: "7 steps" },
    { arrow: "→", text: "resolving node types + dependencies" },
    { arrow: "→", text: "mapping to graph · ", em: "7 nodes, 8 edges" },
    { arrow: "→", text: "arranging layout ", wire: "left → right, by depth", done: true },
  ];

  const learn = () => {
    setStage("learning"); setWired(0);
    run(SCRIPT, () => {
      setStage("done");
      // wire nodes in one by one
      NODES.forEach((_, i) => setTimeout(() => setWired(w => Math.max(w, i + 1)), (reduceMotion ? 40 : 160) * i));
    });
  };

  return (
    <section className="section" id="eye-b" ref={ref}>
      <div className="wrap">
        <SectionHead idx="EYE B — 02" kind="LEARN" title="From a tutorial" sub="A walkthrough is a program described in prose. Grain pulls the transcript, recovers the procedure, and rebuilds it as a labeled, arranged node network — not a transcript, a graph you can run." shown={shown} motif="assets/eye-b-learn.png" accent="var(--wire)" />

        <div className={`panel eyea-panel ${shown ? "in" : ""}`} style={{ marginTop: 56 }}>
          <div className="panel-head">
            <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <span className="panel-dots"><i></i><i></i><i></i></span>
              <span className="panel-title">grain · learn.tutorial</span>
            </div>
            <span className="panel-title" style={{ color: stage === "done" ? "var(--wire)" : "var(--text-faint)" }}>
              {stage === "idle" ? "READY" : stage === "learning" ? "LEARNING…" : "● GRAPH BUILT"}
            </span>
          </div>

          <div className="eyeb-grid">
            <div className="eyeb-left">
              <label className="param-label" style={{ display: "block", marginBottom: 9, color: "var(--text-faint)" }}>// tutorial url</label>
              <div className="field" style={{ marginBottom: 14 }}>
                <span className="prefix">▶</span>
                <input value="youtube.com/watch?v=procedural-planet" readOnly spellCheck={false} />
              </div>
              <button className="btn btn-grain" onClick={learn} disabled={running} style={{ marginBottom: 18 }}>
                {running ? "Learning…" : stage === "done" ? "Learn again" : "Learn"}
                <span style={{ fontSize: 15 }}>↻</span>
              </button>

              <div className="feed eyeb-feed" ref={feedRef}>
                {lines.length === 0 && stage === "idle" && (
                  <div className="faint" style={{ opacity: 0.7 }}>// press <span className="mono" style={{ color: "var(--grain)" }}>Learn</span> to extract the procedure</div>
                )}
                {lines.map((ln, i) => (
                  <div key={i} className={`feed-line ${ln.done ? "done" : ""}`}>
                    <span className="arrow">{ln.arrow}</span>
                    <span className="body">{ln.text}{ln.em && <span className="em">{ln.em}</span>}{ln.wire && <span className="wire">{ln.wire}</span>}</span>
                  </div>
                ))}
                {running && <div className="feed-line" style={{ animation: "none", opacity: 1 }}><span className="feed-cursor" /></div>}
              </div>
              <p className="mono faint" style={{ fontSize: 11, marginTop: 14, lineHeight: 1.6 }}>Works best on procedural, node-based tutorials.</p>
            </div>

            <div className="eyeb-right">
              <NodeStage stage={stage} wired={wired} />
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

function NodeStage({ stage, wired }) {
  const pos = id => NODES.find(n => n.id === id);
  const port = (n, side) => ({ x: n.x + (side === "out" ? NODE_W : 0), y: n.y + NODE_H / 2 });
  const visible = id => stage === "done" && NODES.findIndex(n => n.id === id) < wired;

  return (
    <div className="viewport node-vp">
      <div className="vp-grid" />
      <span className="vp-tick tl" /><span className="vp-tick tr" /><span className="vp-tick bl" /><span className="vp-tick br" />
      <div className="vp-label">
        {stage === "done" ? <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--wire)", display: "inline-block", boxShadow: "0 0 8px var(--wire)" }} /> : <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--text-faint)", display: "inline-block" }} />}
        {stage === "idle" ? "EMPTY GRAPH" : stage === "learning" ? "EXTRACTING…" : "NODE NETWORK · 7"}
      </div>

      {stage !== "done" ? (
        <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center" }}>
          <div className="mono faint" style={{ fontSize: 12, textAlign: "center", opacity: 0.6 }}>
            {stage === "learning" ? "◴ recovering procedure…" : "▢ no graph — learn a tutorial"}
          </div>
        </div>
      ) : (
        <div className="node-stage" style={{ position: "absolute", inset: 0, overflow: "auto" }}>
          <div style={{ position: "relative", width: 640, height: 360, margin: "0 auto", transform: "scale(0.96)", transformOrigin: "center" }}>
            <svg width="640" height="360" style={{ position: "absolute", inset: 0, pointerEvents: "none", overflow: "visible" }}>
              {EDGES.map(([a, b], i) => {
                const pa = port(pos(a), "out"), pb = port(pos(b), "in");
                const mx = (pa.x + pb.x) / 2;
                const d = `M ${pa.x} ${pa.y} C ${mx} ${pa.y}, ${mx} ${pb.y}, ${pb.x} ${pb.y}`;
                const on = visible(a) && visible(b);
                return <path key={i} d={d} fill="none" stroke="var(--wire)" strokeWidth="1.5"
                  strokeOpacity={on ? 0.55 : 0} style={{ filter: "drop-shadow(0 0 4px var(--wire-soft))" }} />;
              })}
            </svg>
            {NODES.map((n, i) => {
              const vis = NODES.findIndex(x => x.id === n.id) < wired;
              const tint = n.kind === "input" ? "var(--text-faint)" : n.kind === "output" ? "var(--grain)" : "var(--wire)";
              return (
                <div key={n.id} style={{
                  position: "absolute", left: n.x, top: n.y, width: NODE_W, height: NODE_H,
                  background: "var(--surface-2)", border: `1px solid ${n.kind === "output" ? "var(--grain-deep)" : "var(--hairline)"}`,
                  borderRadius: 9, padding: "8px 11px",
                  boxShadow: n.kind === "output" ? "0 0 18px var(--grain-glow)" : "0 6px 18px rgba(0,0,0,0.4)",
                  opacity: vis ? 1 : 0, transform: vis ? "translateY(0) scale(1)" : "translateY(8px) scale(0.9)",
                  transition: "transform 0.5s var(--spring)",
                }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    <span style={{ width: 6, height: 6, borderRadius: 2, background: tint, flexShrink: 0 }} />
                    <span className="mono" style={{ fontSize: 11.5, color: "var(--text)", letterSpacing: "-0.01em" }}>{n.label}</span>
                  </div>
                  <div className="mono" style={{ fontSize: 10, color: "var(--text-faint)", marginTop: 4, paddingLeft: 12 }}>{n.val}</div>
                  {/* ports */}
                  <span style={{ position: "absolute", left: -4, top: NODE_H / 2 - 4, width: 7, height: 7, borderRadius: "50%", background: "var(--surface-3)", border: "1px solid var(--hairline)" }} />
                  <span style={{ position: "absolute", right: -4, top: NODE_H / 2 - 4, width: 7, height: 7, borderRadius: "50%", background: tint }} />
                </div>
              );
            })}
          </div>
        </div>
      )}
      <span className="mono" style={{ position: "absolute", bottom: 10, right: 14, zIndex: 5, fontSize: 9.5, color: "var(--text-faint)", letterSpacing: "0.08em" }}>{stage === "done" ? "auto-arranged · L→R" : ""}</span>
    </div>
  );
}

Object.assign(window, { EyeB, NodeStage });
