// Shared UI primitives used across screens
const { useState, useEffect, useMemo, useRef } = React;

const Avatar = ({ user, size = 28 }) => (
  <div className="avatar" style={{ background: user.color, width: size, height: size, fontSize: size < 28 ? 9 : 11 }}>
    {user.avatar}
  </div>
);

const Pill = ({ status, children, className = "" }) => {
  const c = status ? status.toLowerCase() : "";
  return <span className={`pill ${c} ${className}`}>{children || status}</span>;
};

const KPI = ({ label, value, delta, deltaDir, sub }) => (
  <div className="kpi">
    <div className="kpi-label">{label}</div>
    <div className="kpi-value mono">{value}</div>
    {delta && <div className={`kpi-delta ${deltaDir || ""}`}>{delta}</div>}
    {sub && <div className="kpi-delta">{sub}</div>}
  </div>
);

const PageHeader = ({ title, sub, right }) => (
  <div className="page-header">
    <div>
      <h1 className="page-title">{title}</h1>
      {sub && <div className="page-sub">{sub}</div>}
    </div>
    {right && <div className="row gap-8">{right}</div>}
  </div>
);

const Card = ({ title, sub, right, children, foot, style }) => (
  <div className="card" style={style}>
    {(title || right) && (
      <div className="card-head">
        <div>
          {title && <div className="card-title">{title}</div>}
          {sub && <div className="card-sub">{sub}</div>}
        </div>
        {right && <div style={{ marginLeft: "auto" }}>{right}</div>}
      </div>
    )}
    {children}
    {foot && <div className="card-head" style={{ borderBottom: 0, borderTop: "1px solid var(--line)", background: "#fafbfc" }}>{foot}</div>}
  </div>
);

const FilterChip = ({ keyLabel, value, set, onClear, onClick }) => (
  <button className={`filter-chip ${set ? "set" : ""}`} onClick={onClick} style={{ cursor: "pointer" }}>
    <span className="key">{keyLabel}</span>
    {set ? <b>{value}</b> : <span className="muted">Any</span>}
    {set && onClear && <span onClick={(e) => { e.stopPropagation(); onClear(); }} style={{ marginLeft: 2, color: "var(--ink-mute)" }}>×</span>}
    {!set && <Icon name="chevron" size={10} />}
  </button>
);

const Stepper = ({ steps, current }) => (
  <div className="stepper">
    {steps.map((s, i) => (
      <React.Fragment key={i}>
        <div className={`step ${i === current ? "active" : i < current ? "done" : ""}`}>
          <div className="n">{i < current ? "✓" : i + 1}</div>
          <span>{s}</span>
        </div>
        {i < steps.length - 1 && <div className="step-line" />}
      </React.Fragment>
    ))}
  </div>
);

const Tabs = ({ tabs, current, onChange }) => (
  <div className="tabs">
    {tabs.map((t) => (
      <button
        key={t.id}
        className={`tab ${current === t.id ? "active" : ""}`}
        onClick={() => onChange(t.id)}
      >
        {t.label}
        {t.count != null && <span className="count">{t.count}</span>}
      </button>
    ))}
  </div>
);

const SlideOver = ({ open, onClose, title, sub, children, foot, wide }) => {
  if (!open) return null;
  return (
    <>
      <div className="scrim" onClick={onClose} />
      <div className={`slideover ${wide ? "wide" : ""}`}>
        <div className="so-head">
          <div>
            <div className="title">{title}</div>
            {sub && <div className="sub">{sub}</div>}
          </div>
          <button className="icon-btn" onClick={onClose} style={{ marginLeft: "auto" }}>
            <Icon name="close" size={14} />
          </button>
        </div>
        <div className="so-body">{children}</div>
        {foot && <div className="so-foot">{foot}</div>}
      </div>
    </>
  );
};

const Toast = ({ msg, onClose }) => {
  useEffect(() => {
    if (!msg) return;
    const t = setTimeout(onClose, 3000);
    return () => clearTimeout(t);
  }, [msg]);
  if (!msg) return null;
  return (
    <div className="toast">
      <Icon name="check" size={14} stroke="#7fd9b0" />
      {msg}
    </div>
  );
};

const MiniBars = ({ data, highlight }) => (
  <div className="bars">
    {data.map((v, i) => (
      <div key={i} className={`bar ${i === highlight ? "" : "dim"}`} style={{ height: `${Math.max(8, v * 100)}%` }} />
    ))}
  </div>
);

// Field with label
const Field = ({ label, required, hint, children, span }) => (
  <div className="field" style={span ? { gridColumn: `span ${span}` } : undefined}>
    <label>{label} {required && <span className="req">*</span>}</label>
    {children}
    {hint && <div className="tiny muted">{hint}</div>}
  </div>
);

// Format helpers
const fmt = {
  num(n, d = 2) {
    if (n == null || isNaN(n)) return "—";
    return Number(n).toLocaleString("en-US", { minimumFractionDigits: d, maximumFractionDigits: d });
  },
  usd(n) {
    return "$" + fmt.num(n, 2);
  },
  date(s) {
    if (!s) return "—";
    return s.length > 10 ? s : s;
  },
};

// Sparkline SVG (rolling time series)
const Sparkline = ({ data, w = 80, h = 22, color = "var(--teal)", fill = false, strokeWidth = 1.4 }) => {
  if (!data || data.length === 0) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const points = data.map((d, i) => `${(i / (data.length - 1)) * w},${h - ((d - min) / range) * (h - 2) - 1}`).join(" ");
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      {fill && <polyline points={`0,${h} ${points} ${w},${h}`} fill={color} opacity="0.12" />}
      <polyline points={points} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
};

// Horizontal pace gauge — value vs target
const PaceGauge = ({ value, target, width = 160 }) => {
  const pct = Math.max(0, Math.min(1.2, value / target));
  const color = pct < 0.95 ? "var(--red)" : pct < 1.05 ? "var(--amber)" : "var(--green)";
  return (
    <div style={{ width, position: "relative" }}>
      <div style={{ height: 8, background: "var(--paper-2)", borderRadius: 4, overflow: "hidden", position: "relative" }}>
        <div style={{ width: `${Math.min(100, (pct / 1.2) * 100)}%`, height: "100%", background: color, transition: "width 0.3s" }} />
        <div style={{ position: "absolute", left: `${(1 / 1.2) * 100}%`, top: -2, bottom: -2, width: 2, background: "var(--ink)" }} />
      </div>
      <div className="row" style={{ justifyContent: "space-between", marginTop: 2 }}>
        <span className="tiny mono" style={{ color }}>{(pct * 100).toFixed(0)}%</span>
        <span className="tiny mono muted">target {fmt.num(target / 1000, 0)}k</span>
      </div>
    </div>
  );
};

// Donut / progress ring
const Ring = ({ pct, size = 56, stroke = 6, color = "var(--teal)", track = "var(--paper-2)", label }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - Math.max(0, Math.min(1, pct / 100)));
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={track} strokeWidth={stroke} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={color} strokeWidth={stroke} strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round" />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center" }}>
        <span className="mono bold" style={{ fontSize: size > 48 ? 12 : 10 }}>{label || `${Math.round(pct)}%`}</span>
      </div>
    </div>
  );
};

Object.assign(window, { Avatar, Pill, KPI, PageHeader, Card, FilterChip, Stepper, Tabs, SlideOver, Toast, MiniBars, Field, fmt, Sparkline, PaceGauge, Ring });
