// Shared UI primitives — keep these small, no surface-specific logic here.
// Buttons, pills, tooltips, sparkline, mono cells, sortable table header, etc.

// ── Buttons ────────────────────────────────────────────────────────────────
function Btn({ children, variant = "filled", size = "sm", icon: Icon, onClick, title, disabled, tone, type, danger, style }) {
  const cls = ["btn", `btn-${size}`, `btn-${variant}`, tone && `btn-tone-${tone}`, danger && "btn-danger"]
    .filter(Boolean).join(" ");
  return (
    <button type={type || "button"} className={cls} onClick={onClick} title={title} disabled={disabled} style={style}>
      {Icon ? <Icon size={size === "xs" ? 12 : 14} /> : null}
      {children ? <span>{children}</span> : null}
    </button>
  );
}

// Icon-only outlined action button (matches the existing PrimeVue pattern:
// size="small" severity="secondary" rounded outlined)
function ActionIcon({ icon: Icon, label, onClick, danger, active }) {
  return (
    <button className={`action-icon ${active ? "is-active" : ""} ${danger ? "is-danger" : ""}`}
      onClick={onClick} title={label} aria-label={label}>
      <Icon size={14} />
    </button>
  );
}

// ── Status pill ────────────────────────────────────────────────────────────
const STATUS_MAP = {
  pending:  { label: "Pending",   tone: "amber" },
  approved: { label: "Approved",  tone: "green" },
  green:    { label: "Approved",  tone: "green" },
  rejected: { label: "Rejected",  tone: "red" },
  red:      { label: "Rejected",  tone: "red" },
  on_hold:  { label: "On Hold",   tone: "slate" },
  init:     { label: "Init",      tone: "slate" },
  abandoned:{ label: "Abandoned", tone: "slate" },
  low:      { label: "Low",       tone: "green" },
  medium:   { label: "Medium",    tone: "amber" },
  high:     { label: "High",      tone: "red" },
};
function StatusPill({ status, label, tone }) {
  const m = STATUS_MAP[status] || { label: label || status, tone: tone || "slate" };
  return (
    <span className={`pill pill-${m.tone}`}>
      <span className={`pill-dot pill-dot-${m.tone}`} />
      <span>{m.label}</span>
    </span>
  );
}

// ── Risk score (0–100) with color band ─────────────────────────────────────
function RiskScore({ value, size = "sm" }) {
  const band = value >= 70 ? "red" : value >= 40 ? "amber" : "green";
  return (
    <span className={`risk-score risk-${band} risk-${size}`}>
      <span className="risk-bar"><span className="risk-bar-fill" style={{ width: `${Math.min(value, 100)}%` }} /></span>
      <span className="risk-num tnum mono">{value}</span>
    </span>
  );
}

// ── SLA age — tints amber past 7d, red past 30d ────────────────────────────
function SlaAge({ days }) {
  const tone = days >= 30 ? "red" : days >= 7 ? "amber" : "fg-3";
  return <span className={`sla sla-${tone}`}>Pending {days}d</span>;
}

// ── Flag / country ─────────────────────────────────────────────────────────
function Flag({ code, showName = false }) {
  const c = window.COUNTRIES[code];
  if (!c) return <span className="mono fg-4">{code}</span>;
  return (
    <span className="flag" title={c.name}>
      <span className="flag-glyph" aria-hidden="true">{c.flag}</span>
      {showName ? <span>{c.name}</span> : null}
    </span>
  );
}

// ── Mono cell (truncates middle for addresses) ─────────────────────────────
function Mono({ children, dim }) {
  return <span className={`mono ${dim ? "fg-4" : ""}`}>{children}</span>;
}

// ── Sparkline (inline SVG, ~64×16) ─────────────────────────────────────────
function Sparkline({ data, w = 64, h = 16, tone = "fg-3" }) {
  if (!data || !data.length) return null;
  const max = Math.max(...data), min = Math.min(...data);
  const r = max - min || 1;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * (w - 2) + 1;
    const y = h - 1 - ((v - min) / r) * (h - 2);
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(" ");
  return (
    <svg width={w} height={h} className={`spark spark-${tone}`} viewBox={`0 0 ${w} ${h}`}>
      <polyline points={pts} fill="none" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

// ── Money formatter (matches agio-utils formatUsd contract) ────────────────
function formatUsd(n, opts = {}) {
  if (n == null) return "—";
  const { showCents = false } = opts;
  return new Intl.NumberFormat("en-US", {
    style: "currency", currency: "USD",
    minimumFractionDigits: showCents ? 2 : 0,
    maximumFractionDigits: showCents ? 2 : 0,
  }).format(n);
}
function formatDate(s) {
  if (!s) return "—";
  const d = new Date(s);
  return d.toISOString().slice(0, 10);
}
function formatTime(s) {
  if (!s) return "—";
  const d = new Date(s);
  return d.toISOString().slice(11, 16) + "Z";
}

// ── Card / Panel chrome ────────────────────────────────────────────────────
function Card({ title, hint, actions, children, dense, className = "" }) {
  return (
    <section className={`card ${dense ? "card-dense" : ""} ${className}`}>
      {(title || actions) && (
        <header className="card-hd">
          <div className="card-hd-l">
            {title ? <h3>{title}</h3> : null}
            {hint ? <span className="card-hint">{hint}</span> : null}
          </div>
          {actions ? <div className="card-hd-r">{actions}</div> : null}
        </header>
      )}
      <div className="card-body">{children}</div>
    </section>
  );
}

// ── Segmented control (filled tabs) ────────────────────────────────────────
function Segmented({ value, onChange, options }) {
  return (
    <div className="segmented" role="tablist">
      {options.map(o => (
        <button key={o.value} role="tab" aria-selected={value === o.value}
          className={`seg ${value === o.value ? "is-active" : ""}`}
          onClick={() => onChange(o.value)}>
          {o.label}
          {o.count != null ? <span className="seg-count">{o.count}</span> : null}
        </button>
      ))}
    </div>
  );
}

// ── Filter chip (dropdown placeholder) ─────────────────────────────────────
function FilterChip({ label, value, active, onClick }) {
  return (
    <button className={`fchip ${active ? "is-active" : ""}`} onClick={onClick}>
      <span className="fchip-l">{label}</span>
      <span className="fchip-v">{value || "Any"}</span>
      <IChevronD size={12} />
    </button>
  );
}

// ── Toggle (filter "needs my decision") ────────────────────────────────────
function Toggle({ on, onChange, label }) {
  return (
    <label className={`toggle ${on ? "is-on" : ""}`}>
      <input type="checkbox" checked={on} onChange={e => onChange(e.target.checked)} />
      <span className="toggle-track"><span className="toggle-thumb" /></span>
      <span className="toggle-label">{label}</span>
    </label>
  );
}

// ── Checkbox (compact) ─────────────────────────────────────────────────────
function Check({ checked, indeterminate, onChange, label }) {
  const ref = React.useRef(null);
  React.useEffect(() => { if (ref.current) ref.current.indeterminate = !!indeterminate; }, [indeterminate]);
  return (
    <label className="check">
      <input ref={ref} type="checkbox" checked={!!checked} onChange={e => onChange?.(e.target.checked)} />
      <span className="check-box"><ICheck size={10} /></span>
      {label ? <span>{label}</span> : null}
    </label>
  );
}

// ── Keyboard shortcut hint ─────────────────────────────────────────────────
function Kbd({ children }) { return <kbd className="kbd">{children}</kbd>; }

// ── Empty state ────────────────────────────────────────────────────────────
function Empty({ title, hint, cta }) {
  return (
    <div className="empty">
      <div className="empty-icon"><ICircle size={28} /></div>
      <div className="empty-title">{title}</div>
      {hint ? <div className="empty-hint">{hint}</div> : null}
      {cta ? <div className="empty-cta">{cta}</div> : null}
    </div>
  );
}

Object.assign(window, {
  Btn, ActionIcon, StatusPill, RiskScore, SlaAge, Flag, Mono, Sparkline,
  formatUsd, formatDate, formatTime, Card, Segmented, FilterChip, Toggle,
  Check, Kbd, Empty,
});
