/* ============================================================
   components.jsx — UI primitives for the instrument.
   Status is always shape + text + color, never color alone.
   Exports to window.
   ============================================================ */
(function () {

  // ---- layout ---------------------------------------------
  function Card({ tone = "surface", pad = 16, children, style, className = "", ...rest }) {
    const bg = tone === "sunken" ? "var(--bg-sunken)" : tone === "raised" ? "var(--surface-raised)" : "var(--surface)";
    return (
      <div className={"occ-card " + className} style={{
        background: bg, border: "1px solid var(--line)", borderRadius: "var(--r)",
        padding: pad, boxShadow: tone === "raised" ? "var(--shadow-card)" : "none", ...style,
      }} {...rest}>{children}</div>
    );
  }

  function Row({ children, gap = 8, align = "center", justify = "flex-start", wrap = false, style }) {
    return <div style={{ display: "flex", alignItems: align, justifyContent: justify, gap, flexWrap: wrap ? "wrap" : "nowrap", ...style }}>{children}</div>;
  }

  function Label({ children, style }) {
    return <span className="mono-label" style={style}>{children}</span>;
  }

  // ---- status mark (shape-coded, a11y safe) ----------------
  // good ▸ ring  · attn ▸ caret-up  · acute ▸ bang  · within ▸ dash · low ▸ hollow
  function StatusMark({ status = "within", size = 14 }) {
    const c = { good: "var(--good)", attn: "var(--attn)", acute: "var(--acute)", within: "var(--ink-3)", lowconf: "var(--ink-4)" }[status];
    const s = size;
    if (status === "acute") return (
      <svg width={s} height={s} viewBox="0 0 14 14"><path d="M7 1.5 L13 12 L1 12 Z" fill="none" stroke={c} strokeWidth="1.5" strokeLinejoin="round" /><line x1="7" y1="5.5" x2="7" y2="8.6" stroke={c} strokeWidth="1.5" strokeLinecap="round" /><circle cx="7" cy="10.3" r="0.9" fill={c} /></svg>
    );
    if (status === "attn") return (
      <svg width={s} height={s} viewBox="0 0 14 14"><circle cx="7" cy="7" r="6" fill="none" stroke={c} strokeWidth="1.4" /><path d="M4.4 8 L7 5 L9.6 8" fill="none" stroke={c} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /></svg>
    );
    if (status === "good") return (
      <svg width={s} height={s} viewBox="0 0 14 14"><circle cx="7" cy="7" r="6" fill="none" stroke={c} strokeWidth="1.4" /><circle cx="7" cy="7" r="2.4" fill={c} /></svg>
    );
    if (status === "lowconf") return (
      <svg width={s} height={s} viewBox="0 0 14 14"><circle cx="7" cy="7" r="6" fill="none" stroke={c} strokeWidth="1.3" strokeDasharray="2 2" /></svg>
    );
    return <svg width={s} height={s} viewBox="0 0 14 14"><line x1="3" y1="7" x2="11" y2="7" stroke={c} strokeWidth="1.6" strokeLinecap="round" /></svg>;
  }

  // ---- confidence meter (signal bars) ----------------------
  function ConfidenceMeter({ level = "high", pct, showText = true, size = 1 }) {
    const fill = { high: 3, medium: 2, low: 1 }[level];
    const col = level === "low" ? "var(--ink-4)" : level === "medium" ? "var(--ink-2)" : "var(--good)";
    const bw = 3.5 * size, gap = 2 * size;
    return (
      <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
        <span style={{ display: "inline-flex", alignItems: "flex-end", gap }}>
          {[0, 1, 2].map((i) => (
            <span key={i} style={{ width: bw, height: (5 + i * 3.5) * size, borderRadius: 1, background: i < fill ? col : "var(--line-strong)" }} />
          ))}
        </span>
        {showText && <Label style={{ color: col, letterSpacing: "0.06em", whiteSpace: "nowrap" }}>{level}{pct != null ? ` · ${pct}%` : ""}</Label>}
      </span>
    );
  }

  // ---- chip ------------------------------------------------
  function Chip({ tone = "neutral", children, style, mono = true }) {
    const map = {
      neutral: ["var(--surface-2)", "var(--ink-2)", "var(--line)"],
      good: ["var(--good-soft)", "var(--good-ink)", "var(--good-line)"],
      attn: ["var(--attn-soft)", "var(--attn-ink)", "var(--attn-line)"],
      acute: ["var(--acute-soft)", "var(--acute-ink)", "var(--acute-line)"],
    };
    const [bg, fg, bd] = map[tone] || map.neutral;
    return (
      <span style={{
        display: "inline-flex", alignItems: "center", gap: 5, background: bg, color: fg,
        border: `1px solid ${bd}`, borderRadius: 999, padding: "3px 9px",
        fontFamily: mono ? "var(--font-mono)" : "var(--font-ui)", fontSize: 10.5, fontWeight: 500,
        letterSpacing: "0.04em", textTransform: "uppercase", whiteSpace: "nowrap", ...style,
      }}>{children}</span>
    );
  }

  // ---- delta tag (vs baseline) -----------------------------
  function Delta({ children, tone = "neutral" }) {
    const col = tone === "good" ? "var(--good-ink)" : tone === "attn" ? "var(--attn-ink)" : "var(--ink-3)";
    return <span className="num" style={{ fontSize: 11.5, color: col, fontWeight: 500 }}>{children}</span>;
  }

  // ---- big numeric readout ---------------------------------
  function Readout({ value, unit, band, size = 64, status, color }) {
    const col = color || (status ? { good: "var(--good)", attn: "var(--attn)", acute: "var(--acute)" }[status] : "var(--ink)") || "var(--ink)";
    return (
      <span style={{ display: "inline-flex", alignItems: "baseline", gap: 6, whiteSpace: "nowrap" }}>
        <span className="readout" style={{ fontSize: size, color: col }}>{value}</span>
        {band != null && <span className="num" style={{ fontSize: size * 0.32, color: "var(--ink-3)", fontWeight: 500, whiteSpace: "nowrap" }}>±{band}</span>}
        {unit && <span className="mono-label" style={{ fontSize: size * 0.2, color: "var(--ink-3)" }}>{unit}</span>}
      </span>
    );
  }

  // ---- tier header -----------------------------------------
  function TierHeader({ tier, title, count, note }) {
    const accent = { acute: "var(--acute)", subacute: "var(--attn)", chronic: "var(--ink-3)", wellness: "var(--good)" }[tier] || "var(--ink-3)";
    return (
      <Row justify="space-between" style={{ margin: "2px 2px 9px" }}>
        <Row gap={8}>
          <span style={{ width: 3, height: 12, borderRadius: 2, background: accent }} />
          <Label style={{ color: "var(--ink-2)" }}>{title}</Label>
        </Row>
        {count != null && <Label style={{ color: "var(--ink-4)" }}>{count}</Label>}
        {note && <Label style={{ color: "var(--ink-4)", textTransform: "none", letterSpacing: 0 }}>{note}</Label>}
      </Row>
    );
  }

  // ---- caveat block (clinical humility) --------------------
  function Caveat({ children, action, tone = "neutral" }) {
    const bd = tone === "acute" ? "var(--acute-line)" : tone === "attn" ? "var(--attn-line)" : "var(--line)";
    return (
      <div style={{ borderTop: `1px solid ${bd}`, marginTop: 12, paddingTop: 11 }}>
        <Row gap={8} align="flex-start">
          <svg width="14" height="14" viewBox="0 0 14 14" style={{ flexShrink: 0, marginTop: 1 }}>
            <circle cx="7" cy="7" r="6" fill="none" stroke="var(--ink-4)" strokeWidth="1.3" />
            <line x1="7" y1="6" x2="7" y2="10" stroke="var(--ink-4)" strokeWidth="1.3" strokeLinecap="round" />
            <circle cx="7" cy="4" r="0.85" fill="var(--ink-4)" />
          </svg>
          <span style={{ fontSize: 12.5, lineHeight: 1.5, color: "var(--ink-3)", textWrap: "pretty" }}>{children}</span>
        </Row>
        {action && (
          <button className="occ-confirm" style={{
            marginTop: 11, width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between",
            background: "transparent", border: `1px solid ${bd}`, borderRadius: "var(--r-sm)",
            padding: "9px 12px", color: "var(--ink)", fontSize: 13, fontWeight: 600,
          }}>
            <span>{action}</span>
            <svg width="15" height="15" viewBox="0 0 15 15"><path d="M5 3 L10 7.5 L5 12" fill="none" stroke="var(--ink-3)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /></svg>
          </button>
        )}
      </div>
    );
  }

  // ---- section divider label -------------------------------
  function SubLabel({ children, right }) {
    return (
      <Row justify="space-between" style={{ margin: "0 0 8px" }}>
        <Label>{children}</Label>
        {right && <Label style={{ color: "var(--ink-4)" }}>{right}</Label>}
      </Row>
    );
  }

  // ---- icon (minimal line glyphs) --------------------------
  function Icon({ name, size = 20, color = "currentColor", stroke = 1.6 }) {
    const p = { fill: "none", stroke: color, strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" };
    const paths = {
      home: <><path d="M3 9 L10 3.5 L17 9" {...p} /><path d="M5 8.5 V16.5 H15 V8.5" {...p} /></>,
      heart: <><path d="M10 16 C3 11 3 6 6 5 C8 4.3 9.3 5.5 10 7 C10.7 5.5 12 4.3 14 5 C17 6 17 11 10 16 Z" {...p} /></>,
      moon: <><path d="M15 11 A6 6 0 1 1 9 4.2 A4.6 4.6 0 0 0 15 11 Z" {...p} /></>,
      trend: <><path d="M3 13 L7.5 8 L10.5 11 L17 4.5" {...p} /><path d="M13 4.5 H17 V8.5" {...p} /></>,
      clinical: <><rect x="4" y="4" width="12" height="12" rx="2" {...p} /><path d="M4 11 H7 L8.5 8 L10.5 13 L12 11 H16" {...p} /></>,
      sun: <><circle cx="10" cy="10" r="3.4" {...p} />{[0, 45, 90, 135, 180, 225, 270, 315].map((a) => { const r = a * Math.PI / 180; return <line key={a} x1={10 + 5.4 * Math.cos(r)} y1={10 + 5.4 * Math.sin(r)} x2={10 + 7 * Math.cos(r)} y2={10 + 7 * Math.sin(r)} {...p} />; })}</>,
      back: <><path d="M12 4 L6 10 L12 16" {...p} /></>,
      gap: <><path d="M4 14 L8 7" {...p} /><path d="M12 7 L16 14" {...p} /><line x1="9.2" y1="10.5" x2="10.8" y2="10.5" {...p} strokeDasharray="0.5 2" /></>,
    };
    return <svg width={size} height={size} viewBox="0 0 20 20" style={{ display: "block" }}>{paths[name]}</svg>;
  }

  Object.assign(window, { Card, Row, Label, StatusMark, ConfidenceMeter, Chip, Delta, Readout, TierHeader, Caveat, SubLabel, Icon });
})();
