/* === Shared UI primitives === */

const RAG_LABEL = { green: "On track", yellow: "Needs note", red: "At risk" };

function RagDot({ rag = "green", label = true, size = "md" }) {
  const cls = `rag rag--${rag}`;
  const dotStyle = size === "sm" ? { width: 6, height: 6 } : size === "lg" ? { width: 10, height: 10 } : {};
  return (
    <span className={cls}>
      <span className="rag__dot" style={dotStyle}></span>
      {label && <span>{RAG_LABEL[rag]}</span>}
    </span>
  );
}

function RagBadge({ rag, size = "md" }) {
  const map = {
    green:  { text: "GREEN",  bg: "var(--green-bg)",  fg: "var(--green)",                border: "var(--green)"  },
    yellow: { text: "YELLOW", bg: "var(--yellow-bg)", fg: "oklch(0.4 0.1 60)",           border: "var(--yellow)" },
    red:    { text: "RED",    bg: "var(--red-bg)",    fg: "var(--red)",                  border: "var(--red)"    },
  }[rag];
  if (!map) return null;
  const fontSize = size === "sm" ? 10 : 11;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      fontFamily: "var(--serif)", fontSize, fontWeight: 600,
      padding: "3px 8px", borderRadius: 3,
      letterSpacing: ".06em",
      background: map.bg, color: map.fg,
      border: `1px solid ${map.border}`,
      whiteSpace: "nowrap",
    }}>
      <span style={{ width: 7, height: 7, borderRadius: 99, background: map.border }}></span>
      {map.text}
    </span>
  );
}

function Chip({ kind = "default", children, dot, mono = true }) {
  const cls = `chip ${kind === "default" ? "" : `chip--${kind}`}`;
  return (
    <span className={cls} style={!mono ? { fontFamily: "var(--sans)" } : null}>
      {dot ? <span className="chip__dot"></span> : null}
      {children}
    </span>
  );
}

function ProgressBar({ value, max, rag = "green", showTarget = true }) {
  const pct = Math.min(100, Math.round((value / max) * 100));
  return (
    <div className={`prog prog--${rag}`}>
      <div className="prog__fill" style={{ width: `${pct}%` }}></div>
      {showTarget ? <div className="prog__target" style={{ left: "100%" }}></div> : null}
    </div>
  );
}

function Eyebrow({ children }) {
  return <div className="eyebrow">{children}</div>;
}

function SectionHead({ title, sub, right }) {
  return (
    <div className="section-head">
      <div>
        <div className="section-title">{title}</div>
        {sub ? <div className="section-sub">{sub}</div> : null}
      </div>
      {right ? <div>{right}</div> : null}
    </div>
  );
}

function ODAChip({ id, withTitle = false }) {
  // ODA flat lookup
  let title = "";
  if (withTitle && window.ODA) {
    for (const o of window.ODA) {
      if (o.id === id) { title = o.short; break; }
      for (const d of o.deliverables) if (d.id === id) { title = d.title; break; }
    }
  }
  return <span className="chip chip--navy" title={title || id}><span className="chip__dot"></span>{id}</span>;
}

function Firmness({ kind }) {
  const map = {
    locked:    { label: "LOCKED",    color: "var(--firm-locked)" },
    quoted:    { label: "QUOTED",    color: "var(--firm-quoted)" },
    estimated: { label: "ESTIMATED", color: "var(--firm-estimated)" },
  }[kind];
  return (
    <span style={{
      fontFamily: "var(--mono)", fontSize: 10, fontWeight: 600,
      color: map.color, letterSpacing: ".12em",
      borderBottom: kind === "estimated" ? "1px dashed currentColor" : kind === "quoted" ? "1px dotted currentColor" : "1px solid currentColor",
      paddingBottom: 1,
    }}>{map.label}</span>
  );
}

function PartyChip({ label, party }) {
  const color = party === "R" ? "var(--red)" : party === "D" ? "var(--navy)" : "var(--ink-mute)";
  const bg    = party === "R" ? "var(--red-bg)" : party === "D" ? "var(--navy-bg)" : "var(--surface-2)";
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5,
      fontFamily: "var(--mono)", fontSize: 11, fontWeight: 600,
      padding: "2px 7px", borderRadius: 3,
      background: bg, color,
      letterSpacing: ".02em",
    }}>
      <span style={{ color: "var(--ink-mute)", fontWeight: 500 }}>{label}</span>
      <span>{party || "—"}</span>
    </span>
  );
}

function NumericMilestoneCounts({ current, target, secondaryCurrent, secondaryTarget, secondaryLabel, unit }) {
  return (
    <div>
      <div style={{ fontFamily: "var(--serif)", fontSize: 26, fontWeight: 600, lineHeight: 1, color: "var(--ink)" }}>
        {current}<span style={{ fontSize: 14, color: "var(--ink-mute)", fontWeight: 500 }}> / {target}</span>
      </div>
      <div className="eyebrow" style={{ marginTop: 4 }}>{unit}</div>
      {secondaryTarget != null ? (
        <>
          <div style={{ height: 1, background: "var(--rule)", margin: "10px 0 8px" }}></div>
          <div style={{ display: "flex", alignItems: "baseline", gap: 5, justifyContent: "flex-end" }}>
            <span style={{ fontFamily: "var(--serif)", fontSize: 16, fontWeight: 600, color: "var(--ink)", lineHeight: 1 }}>{secondaryCurrent}</span>
            <span style={{ fontFamily: "var(--mono)", fontSize: 11, color: "var(--ink-mute)" }}>of {secondaryTarget}</span>
          </div>
          <div className="eyebrow" style={{ marginTop: 4 }}>{secondaryLabel || "secondary"}</div>
        </>
      ) : null}
    </div>
  );
}

Object.assign(window, { RagDot, RagBadge, Chip, ProgressBar, Eyebrow, SectionHead, ODAChip, Firmness, PartyChip, NumericMilestoneCounts, RAG_LABEL });
