// ui.jsx — shared presentational components. Styling lives in the main HTML.

const { useState, useEffect, useRef } = React;

// ── Pillar glyphs (simple line icons, not emoji) ────────────────────────────
function Glyph({ name, size = 20, color = "currentColor" }) {
  const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none",
    stroke: color, strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (name) {
    case "shield":
      return (<svg {...common}><path d="M12 3l7 3v5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6z" /></svg>);
    case "coin":
      return (<svg {...common}><circle cx="12" cy="12" r="8" /><path d="M12 7v10M9.5 9.2c0-1 1-1.7 2.5-1.7s2.5.7 2.5 1.8c0 2.4-5 1.2-5 3.7 0 1.1 1 1.8 2.5 1.8s2.5-.7 2.5-1.7" /></svg>);
    case "people":
      return (<svg {...common}><circle cx="12" cy="8" r="3" /><path d="M5 20c0-3.5 3-6 7-6s7 2.5 7 6" /></svg>);
    case "globe":
      return (<svg {...common}><circle cx="12" cy="12" r="8.5" /><path d="M3.5 12h17M12 3.5c2.5 2.4 2.5 14.6 0 17M12 3.5c-2.5 2.4-2.5 14.6 0 17" /></svg>);
    case "eye":
      return (<svg {...common}><path d="M2 12s3.5-6.5 10-6.5S22 12 22 12s-3.5 6.5-10 6.5S2 12 2 12z" /><circle cx="12" cy="12" r="2.6" /></svg>);
    default:
      return null;
  }
}

// ── Typewriter: types children (a string) char by char ──────────────────────
function Typewriter({ text, speed = 18, start = true, onDone, className }) {
  const [i, setI] = useState(0);
  const done = i >= text.length;
  useEffect(() => { setI(0); }, [text]);
  useEffect(() => {
    if (!start || done) { if (done && onDone) onDone(); return; }
    const id = setTimeout(() => {
      const ch = text[i];
      if (window.SFX && ch && ch !== " " && Math.random() > 0.25) window.SFX.key();
      setI(i + 1);
    }, speed);
    return () => clearTimeout(id);
  }, [i, start, text, done]);
  return (
    <span className={className}>
      {text.slice(0, i)}
      {!done && <span className="caret">▋</span>}
    </span>
  );
}

// Reveal a list of lines one after another (used for boot/intro).
function LineStream({ lines, speed = 16, lineGap = 320, onDone, className }) {
  const [shown, setShown] = useState(0);
  return (
    <div className={className}>
      {lines.slice(0, shown + 1).map((ln, idx) => (
        <div key={idx} className="stream-line">
          {idx === shown
            ? <Typewriter text={ln} speed={speed} onDone={() => {
                setTimeout(() => {
                  if (shown < lines.length - 1) setShown(shown + 1);
                  else if (onDone) onDone();
                }, lineGap);
              }} />
            : ln}
        </div>
      ))}
    </div>
  );
}

// ── Pillar bar (horizontal) with warning states ─────────────────────────────
function PillarBar({ pillar, value, prev, danger = 20 }) {
  const low = value <= danger;
  const high = value >= 100 - danger;
  const warn = low || high;
  const delta = prev != null ? value - prev : 0;
  return (
    <div className={"pillar" + (warn ? " pillar--warn" : "")}>
      <div className="pillar__head">
        <span className="pillar__icon" style={{ color: pillar.color }}>
          <Glyph name={pillar.glyph} size={18} />
        </span>
        <span className="pillar__label">{pillar.label}</span>
        <span className="pillar__val" style={{ color: warn ? "var(--danger)" : pillar.color }}>
          {Math.round(value)}
          {delta !== 0 && (
            <span className={"pillar__delta " + (delta > 0 ? "up" : "down")}>
              {delta > 0 ? "▲" : "▼"}{Math.abs(delta)}
            </span>
          )}
        </span>
      </div>
      <div className="pillar__track">
        <div className="pillar__fill" style={{ width: value + "%", background: pillar.color }} />
        <span className="pillar__tick" style={{ left: danger + "%" }} />
        <span className="pillar__tick" style={{ left: (100 - danger) + "%" }} />
      </div>
    </div>
  );
}

// ── Delta chips: the transparent "math" on a choice ─────────────────────────
function DeltaChips({ d, pillarMap, show }) {
  if (!show) return <span className="delta-hidden">effects undisclosed</span>;
  const keys = Object.keys(d).filter((k) => d[k] !== 0);
  if (!keys.length) return <span className="delta-hidden">no measurable change</span>;
  return (
    <span className="chips">
      {keys.map((k) => (
        <span key={k} className={"chip " + (d[k] > 0 ? "chip--up" : "chip--down")}
              style={{ "--c": pillarMap[k] ? pillarMap[k].color : "var(--ink-dim)" }}>
          <span className="chip__name">{pillarMap[k] ? pillarMap[k].label : k}</span>
          <span className="chip__num">{d[k] > 0 ? "+" : ""}{d[k]}</span>
        </span>
      ))}
    </span>
  );
}

// ── Stamp: slams a label onto a document (decision feedback) ─────────────────
function Stamp({ label, kind }) {
  return <div className={"stamp stamp--" + kind}><span>{label}</span></div>;
}

// Redaction bar — a censored block of text.
function Redact({ w = 60 }) {
  return <span className="redact" style={{ width: w + "px" }} />;
}

Object.assign(window, { Glyph, Typewriter, LineStream, PillarBar, DeltaChips, Stamp, Redact });
