// ---------- Shared UI primitives ----------

const Btn = ({ children, variant = "default", size, icon, onClick, className = "", style, ...rest }) => (
  <button onClick={onClick} style={style} className={`btn ${variant === "primary" ? "btn-primary" : variant === "ghost" ? "btn-ghost" : ""} ${size === "sm" ? "btn-sm" : ""} ${icon && !children ? "btn-icon" : ""} ${className}`} {...rest}>
    {icon ? <Icon name={icon} /> : null}
    {children}
  </button>
);

const Badge = ({ children, tone = "default", dot = false }) => (
  <span className={`badge ${tone !== "default" ? `badge-${tone}` : ""} ${dot ? "badge-dot" : ""}`}>{children}</span>
);

const Card = ({ title, subtitle, action, children, pad = "default", className = "", style }) => (
  <div className={`card ${className}`} style={style}>
    {(title || action) && (
      <div className="card-head">
        <div>
          {title && <div className="card-title">{title}</div>}
          {subtitle && <div className="card-subtitle">{subtitle}</div>}
        </div>
        {action}
      </div>
    )}
    <div className={pad === "lg" ? "card-pad-lg" : "card-body"}>{children}</div>
  </div>
);

const Field = ({ label, help, children }) => (
  <div className="fld-group">
    {label && <label className="fld-label">{label}</label>}
    {children}
    {help && <div className="fld-help">{help}</div>}
  </div>
);

const Input = (p) => <input className="fld" {...p} />;
const Textarea = (p) => <textarea className="fld" {...p} />;
const Select = ({ children, ...p }) => <select className="fld" {...p}>{children}</select>;

const Toggle = ({ checked, onChange }) => (
  <div className={`tog ${checked ? "on" : ""}`} onClick={() => onChange && onChange(!checked)} />
);

const Tabs = ({ tabs, active, onSelect }) => (
  <div className="tabs">
    {tabs.map(t => (
      <button key={t.id} className={`tab ${active === t.id ? "active" : ""}`} onClick={() => onSelect && onSelect(t.id)}>
        {t.label}{t.badge ? <span className="badge" style={{ marginLeft: 8 }}>{t.badge}</span> : null}
      </button>
    ))}
  </div>
);

const Segmented = ({ options, value, onChange }) => (
  <div className="seg">
    {options.map(o => (
      <button key={o.value} className={value === o.value ? "active" : ""} onClick={() => onChange(o.value)}>{o.label}</button>
    ))}
  </div>
);

const Spark = ({ data, threshold }) => {
  const max = Math.max(...data);
  return (
    <div className="spark">
      {data.map((v, i) => (
        <i key={i} className={threshold && v >= threshold ? "hi" : ""} style={{ height: `${Math.max(8, (v / max) * 100)}%` }} />
      ))}
    </div>
  );
};

const StatTile = ({ k }) => (
  <div className="stat">
    <div className="stat-label">{k.label}</div>
    <div className="stat-value">{k.value}</div>
    <div className="row" style={{ justifyContent: "space-between", marginTop: 10, gap: 12 }}>
      <span className={`stat-delta ${k.deltaBad ? "down" : ""}`}>
        {k.delta?.startsWith("-") ? "↓" : "↑"} {k.delta}
      </span>
      <div style={{ flex: 1, maxWidth: 90 }}><Spark data={k.spark} /></div>
    </div>
  </div>
);

// Smooth line chart
const LineChart = ({ data, height = 260, color = "var(--a)", labels }) => {
  const w = 800;
  const h = height;
  const padL = 52;
  const padR = 20;
  const padT = 16;
  const padB = 32;
  const max = Math.max(...data, 1);
  const min = 0;

  const chartL = padL;
  const chartR = w - padR;
  const chartT = padT;
  const chartB = h - padB;
  const chartW = chartR - chartL;
  const chartH = chartB - chartT;

  const points = data.map((v, i) => {
    const x = chartL + (i / Math.max(data.length - 1, 1)) * chartW;
    const y = chartT + (1 - (v - min) / (max - min)) * chartH;
    return [x, y];
  });

  const path = points.reduce((acc, [x, y], i) => {
    if (i === 0) return `M ${x} ${y}`;
    const [px, py] = points[i - 1];
    const cx = (px + x) / 2;
    return `${acc} Q ${cx} ${py} ${cx} ${(py + y) / 2} T ${x} ${y}`;
  }, "");

  const area = `${path} L ${points[points.length - 1][0]} ${chartB} L ${points[0][0]} ${chartB} Z`;

  const yTicks = [0, 0.25, 0.5, 0.75, 1].map(p => ({
    y: chartB - p * chartH,
    value: Math.round(max * p),
  }));

  return (
    <svg className="chart-svg" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      <defs>
        <linearGradient id="lgArea" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>

      {yTicks.map(({ y, value }, i) => (
        <g key={i}>
          <line x1={chartL} x2={chartR} y1={y} y2={y}
            stroke={i === 0 ? "rgba(255,255,255,0.12)" : "rgba(255,255,255,0.06)"} />
          <text x={chartL - 6} y={y + 3.5}
            fill="var(--c-text-4)" fontSize="11" textAnchor="end"
            fontFamily="var(--f-mono)">{value}</text>
        </g>
      ))}

      <path d={area} fill="url(#lgArea)" />
      <path d={path} fill="none" stroke={color} strokeWidth="1.6" />

      {points.map(([x, y], i) =>
        i === points.length - 1
          ? <circle key={i} cx={x} cy={y} r="3.5" fill={color} stroke="var(--c-bg-2)" strokeWidth="2" />
          : null
      )}

      {labels && labels.map((label, i) => {
        if (!label) return null;
        const x = chartL + (i / Math.max(data.length - 1, 1)) * chartW;
        return (
          <text key={i} x={x} y={h - 8}
            fill="var(--c-text-4)" fontSize="10" textAnchor="middle"
            fontFamily="var(--f-mono)">{label}</text>
        );
      })}
    </svg>
  );
};

// Tall bar chart
const BarChart = ({ data, labels, height = 220, color = "var(--a)" }) => {
  const w = 800;
  const h = height;
  const pad = 28;
  const max = Math.max(...data);
  const barW = (w - pad * 2) / data.length;
  return (
    <svg className="chart-svg" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      {[0.25, 0.5, 0.75].map((p, i) => (
        <line key={i} x1={pad} x2={w - pad} y1={pad + (h - pad * 2) * p} y2={pad + (h - pad * 2) * p} stroke="rgba(255,255,255,0.04)" />
      ))}
      {data.map((v, i) => {
        const x = pad + i * barW + barW * 0.15;
        const bw = barW * 0.7;
        const bh = (v / max) * (h - pad * 2);
        const y = h - pad - bh;
        return (
          <g key={i}>
            <rect x={x} y={y} width={bw} height={bh} rx="2" fill={i === data.length - 2 ? color : "var(--c-elev-2)"} />
            {labels && <text x={x + bw / 2} y={h - 8} fill="var(--c-text-4)" fontSize="9" textAnchor="middle" fontFamily="var(--f-mono)">{labels[i]}</text>}
          </g>
        );
      })}
    </svg>
  );
};

// Donut
const Donut = ({ segments, size = 140, label, sub }) => {
  const r = size / 2 - 12;
  const c = 2 * Math.PI * r;
  const total = segments.reduce((s, x) => s + x.value, 0);
  let off = 0;
  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} stroke="var(--c-surface-2)" strokeWidth="10" fill="none" />
        {segments.map((s, i) => {
          const len = (s.value / total) * c;
          const dash = `${len} ${c - len}`;
          const ret = (
            <circle key={i} cx={size/2} cy={size/2} r={r} stroke={s.color} strokeWidth="10" fill="none"
              strokeDasharray={dash} strokeDashoffset={-off} strokeLinecap="butt" />
          );
          off += len;
          return ret;
        })}
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        <div>
          <div className="mono" style={{ fontSize: 22, letterSpacing: "-0.02em" }}>{label}</div>
          <div className="muted" style={{ fontSize: 10.5, marginTop: 2 }}>{sub}</div>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { Btn, Badge, Card, Field, Input, Textarea, Select, Toggle, Tabs, Segmented, Spark, StatTile, LineChart, BarChart, Donut });
