// OperatorFlow primitives — Logo (3 variants), Pill, CTA, Manifest, Step, RunCard, Diagram, Terminal.

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─────────────────────────────────────────────────────────
// Logo — three glyph variants per DESIGN.md §9
// variant: 'notch' | 'arrow' | 'cursor'
// ─────────────────────────────────────────────────────────
function Logo({ variant = "notch", size = 22, mark = true, wordmark = "operatorflow", style }) {
  const accent = "var(--signal)";
  const ink = "var(--ink)";
  const line = "var(--line-strong)";

  let glyph;
  if (variant === "notch") {
    // A square with a notch carved from the top-right corner.
    // The notch corner itself is filled in signal as a dispatch tag.
    const s = size;
    const n = Math.round(s * 0.34); // notch size
    glyph = (
      <svg className="glyph" viewBox={`0 0 ${s} ${s}`} aria-hidden="true">
        <path
          d={`M0.5 0.5 H${s - n - 0.5} L${s - 0.5} ${n + 0.5} V${s - 0.5} H0.5 Z`}
          fill="none"
          stroke={ink}
          strokeWidth="1.2"
        />
        <path
          d={`M${s - n - 0.5} 0.5 L${s - 0.5} ${n + 0.5} L${s - n - 0.5} ${n + 0.5} Z`}
          fill={accent}
        />
        <line x1={s * 0.22} y1={s * 0.48} x2={s * 0.58} y2={s * 0.48} stroke={ink} strokeOpacity="0.5" strokeWidth="1.2" />
        <line x1={s * 0.22} y1={s * 0.66} x2={s * 0.72} y2={s * 0.66} stroke={ink} strokeOpacity="0.5" strokeWidth="1.2" />
      </svg>
    );
  } else if (variant === "arrow") {
    // Monogram "of" — f's crossbar extends into a right-pointing arrow.
    const s = size;
    glyph = (
      <svg className="glyph" viewBox="0 0 24 24" aria-hidden="true" width={s} height={s}>
        {/* o */}
        <circle cx="7" cy="13.5" r="4.2" fill="none" stroke={ink} strokeWidth="1.8" />
        {/* f stem */}
        <path d="M14.5 21 V8.5 a3 3 0 0 1 3-3 h2" stroke={ink} strokeWidth="1.8" fill="none" strokeLinecap="round" />
        {/* f crossbar → arrow */}
        <path d="M11.6 12.2 H22" stroke={accent} strokeWidth="1.8" strokeLinecap="round" />
        <path d="M19.5 9.7 L22 12.2 L19.5 14.7" stroke={accent} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" fill="none" />
      </svg>
    );
  } else {
    // Cursor — solid block cursor in signal, with a subtle baseline tick.
    const s = size;
    glyph = (
      <svg className="glyph" viewBox="0 0 24 24" aria-hidden="true" width={s} height={s}>
        <rect x="9" y="3.5" width="6" height="14" fill={accent} className="of-cursor-block" />
        <line x1="5" y1="20.5" x2="19" y2="20.5" stroke={ink} strokeOpacity="0.5" strokeWidth="1.4" strokeLinecap="round" />
      </svg>
    );
  }

  return (
    <span className="of-logo" style={style}>
      {mark && glyph}
      {wordmark && (
        <span className="wordmark">
          {wordmark === "operatorflow" ? (
            <>
              <span>operator</span>
              <span className="accent">flow</span>
            </>
          ) : (
            wordmark
          )}
        </span>
      )}
    </span>
  );
}

// ─────────────────────────────────────────────────────────
// Pill — status / availability
// ─────────────────────────────────────────────────────────
function Pill({ variant = "done", children, dot = true, style }) {
  return (
    <span className={`pill ${variant}`} style={style}>
      {dot && <span className="dot" />}
      {children}
    </span>
  );
}

// ─────────────────────────────────────────────────────────
// CTA — primary | ghost, with optional caption
// ─────────────────────────────────────────────────────────
function CTA({ variant = "primary", href, onClick, children, caption, arrow = true }) {
  return (
    <span className="cta">
      <a className={`cta-btn ${variant}`} href={href} onClick={onClick}>
        <span>{children}</span>
        {arrow && <span className="arrow">→</span>}
      </a>
      {caption && <span className="cta-caption">{caption}</span>}
    </span>
  );
}

// ─────────────────────────────────────────────────────────
// Manifest — mono keys, ink values; reads like a config file
// ─────────────────────────────────────────────────────────
function Manifest({ title = "scope.yml", entries, footer }) {
  return (
    <div className="manifest">
      <div className="manifest-head">
        <span>{title}</span>
        {footer && <span>{footer}</span>}
      </div>
      <div className="manifest-body">
        {entries.map((e, i) => (
          <div key={i} className="manifest-row">
            <span className="k">{e.k}</span>
            <span className="v">
              {e.v}
              {e.muted && <span className="muted"> {e.muted}</span>}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// ProblemStep — numbered timeline item, mono number = icon
// ─────────────────────────────────────────────────────────
function ProblemStep({ n, title, children }) {
  return (
    <div className="problem-step" data-reveal>
      <span className="num">
        <span className="accent">{String(n).padStart(2, "0")}</span> ·
      </span>
      <div>
        <h3>{title}</h3>
        <p>{children}</p>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// RunCard — faux ops card. Real workflow, plausible steps.
// ─────────────────────────────────────────────────────────
function RunCard({ name, scope = "", status = "ready", steps, run, foot }) {
  return (
    <div className="runcard" data-reveal>
      <div className="runcard-head">
        <span className="name">
          {name}
          {scope && <span className="scope"> · {scope}</span>}
        </span>
        <Pill variant={status}>{status}</Pill>
      </div>
      <div className="runcard-rows">
        {steps.map((s, i) => (
          <div className="runcard-row" data-status={s.status || "done"} key={i}>
            <span className="ts">{s.ts}</span>
            <span className="dot" />
            <div>
              <div className="step-title">{s.title}</div>
              {s.meta && <div className="step-meta">{s.meta}</div>}
            </div>
            <span className="runtime">{s.ms}</span>
          </div>
        ))}
      </div>
      {foot && (
        <div className="runcard-foot">
          <span>{foot.left}</span>
          {foot.right && <button className="approve">{foot.right}</button>}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// Diagram — animated workflow SVG. Nodes light sequentially.
// ─────────────────────────────────────────────────────────
function Diagram({ title = "workflow · lead-response" }) {
  const [step, setStep] = useState(-1);
  useEffect(() => {
    const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (prefersReduced) {
      setStep(4);
      return;
    }
    let t = -1;
    const ids = [];
    const tick = () => {
      t = (t + 1) % 6; // 5 steps + a pause frame
      setStep(t);
      ids.push(setTimeout(tick, t === 4 ? 1800 : 600));
    };
    tick();
    return () => ids.forEach(clearTimeout);
  }, []);

  // Nodes laid out as a workflow:
  // [inbound] → [classify] → [draft] → [review] → [sent]
  //                              ↓
  //                         [CRM update]
  const nodes = [
    { id: 0, x: 16,  y: 70, w: 96, h: 36, label: "inbound" },
    { id: 1, x: 142, y: 70, w: 100, h: 36, label: "classify" },
    { id: 2, x: 272, y: 70, w: 96, h: 36, label: "ai draft" },
    { id: 3, x: 272, y: 138, w: 96, h: 36, label: "crm sync" },
    { id: 4, x: 398, y: 70, w: 104, h: 36, label: "human ok" },
    { id: 5, x: 532, y: 70, w: 80, h: 36, label: "sent" },
  ];
  const edges = [
    { from: 0, to: 1, step: 0 },
    { from: 1, to: 2, step: 1 },
    { from: 2, to: 3, step: 2, kind: "branch" },
    { from: 2, to: 4, step: 2 },
    { from: 4, to: 5, step: 3 },
  ];
  const active = (idx) => step >= idx;

  return (
    <div className="diagram" data-reveal>
      <div className="diagram-head">
        <span>{title}</span>
        <span style={{ color: "var(--signal)" }}>● running</span>
      </div>
      <svg viewBox="0 0 628 200" preserveAspectRatio="xMidYMid meet">
        {/* edges */}
        {edges.map((e, i) => {
          const a = nodes[e.from], b = nodes[e.to];
          const x1 = a.x + a.w;
          const y1 = a.y + a.h / 2;
          const x2 = b.x;
          const y2 = b.y + b.h / 2;
          let d;
          if (e.kind === "branch") {
            const mid = (a.x + a.w) + (b.x - (a.x + a.w)) / 2;
            d = `M ${a.x + a.w / 2} ${a.y + a.h} V ${b.y + b.h / 2} H ${b.x}`;
          } else {
            d = `M ${x1} ${y1} H ${x2}`;
          }
          return (
            <g key={i}>
              <path d={d} className={`edge ${active(e.step) ? "active" : ""}`} />
              {/* arrowhead */}
              <path
                d={`M ${x2 - 5} ${y2 - 3} L ${x2} ${y2} L ${x2 - 5} ${y2 + 3}`}
                fill="none"
                stroke={active(e.step) ? "var(--signal)" : "var(--line-strong)"}
                strokeWidth="1"
                strokeLinecap="round"
                strokeLinejoin="round"
              />
            </g>
          );
        })}
        {/* nodes */}
        {nodes.map((n, i) => {
          const isActive = active(n.id);
          return (
            <g key={n.id}>
              <rect
                x={n.x}
                y={n.y}
                width={n.w}
                height={n.h}
                rx="3"
                className={`node-rect ${isActive ? "active" : ""}`}
              />
              <text
                x={n.x + n.w / 2}
                y={n.y + n.h / 2 + 4}
                textAnchor="middle"
                className="node-label"
                style={{ fill: isActive ? "var(--signal)" : "var(--ink-muted)" }}
              >
                {n.label}
              </text>
              {/* active dot */}
              {isActive && (
                <circle cx={n.x + 8} cy={n.y + 8} r="2.2" fill="var(--signal)" />
              )}
            </g>
          );
        })}
      </svg>
      <div className="legend">
        <span>● signal = active</span>
        <span style={{ color: "var(--ink-dim)" }}>· dashed = pending</span>
        <span style={{ marginLeft: "auto" }}>5 nodes · 5 edges · 1 branch</span>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// Terminal — dispatch log hero treatment
// ─────────────────────────────────────────────────────────
const TERMINAL_LINES = [
  { ts: "09:14:02", msg: <><span className="agent">agent.lead-response</span> received form-submission #4f2a</>, rt: "" },
  { ts: "09:14:03", msg: <>classifying intent <span className="ok">→ qualified · plumbing · urgent</span></>, rt: "84ms" },
  { ts: "09:14:04", msg: <>drafting reply <span className="ok">→ 142 tokens</span> · adding booking link</>, rt: "1.2s" },
  { ts: "09:14:05", msg: <>posting to <span className="agent">crm.contacts</span> · owner=arnab</>, rt: "0.3s" },
  { ts: "09:14:06", msg: <><span className="warn">awaiting human approval</span> · queue=hello@</>, rt: "—" },
  { ts: "09:18:21", msg: <><span className="agent">arnab</span> approved · sent via gmail</>, rt: "" },
  { ts: "09:18:22", msg: <><span className="ok">workflow complete</span> · next follow-up: t+48h</>, rt: "4m 20s" },
];

function Terminal({ title = "dispatch · live tail" }) {
  const [visible, setVisible] = useState(1);
  useEffect(() => {
    const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (prefersReduced) {
      setVisible(TERMINAL_LINES.length);
      return;
    }
    const ids = [];
    TERMINAL_LINES.forEach((_, i) => {
      ids.push(setTimeout(() => setVisible(i + 1), 350 + i * 380));
    });
    return () => ids.forEach(clearTimeout);
  }, []);

  return (
    <div className="terminal" data-reveal>
      <div className="terminal-head">
        <span className="dots"><i /><i /><i /></span>
        <span>{title}</span>
        <span>tail -f /var/log/of</span>
      </div>
      <div className="terminal-body">
        {TERMINAL_LINES.slice(0, visible).map((l, i) => (
          <div className="terminal-line" key={i}>
            <span className="ts">{l.ts}</span>
            <span className="msg">{l.msg}</span>
            <span className="runtime">{l.rt}</span>
          </div>
        ))}
        {visible < TERMINAL_LINES.length && (
          <div className="terminal-line">
            <span className="ts" />
            <span className="msg"><span className="prompt">▌</span></span>
            <span />
          </div>
        )}
        {visible >= TERMINAL_LINES.length && (
          <div className="terminal-line">
            <span className="ts" />
            <span className="msg"><span className="prompt">$</span> <span style={{ color: "var(--ink-muted)" }}>of run inbox-triage</span><span className="terminal-cursor" /></span>
            <span />
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { Logo, Pill, CTA, Manifest, ProblemStep, RunCard, Diagram, Terminal });
