// Shared small SVG components for Raudhah KPI dashboard
const { useState, useEffect, useMemo, useRef } = React;

function Sparkline({ data, color = "var(--raudhah-pink)", fill = true, height = 34, strokeWidth = 1.6 }) {
  const ref = useRef(null);
  const [w, setW] = useState(120);
  useEffect(() => {
    if (!ref.current) return;
    const ro = new ResizeObserver(() => setW(ref.current.clientWidth));
    ro.observe(ref.current);
    setW(ref.current.clientWidth || 120);
    return () => ro.disconnect();
  }, []);
  const clean = data.filter(v => v != null);
  if (!clean.length) return <div ref={ref} style={{ height }} />;
  const min = Math.min(...clean), max = Math.max(...clean);
  const range = max - min || 1;
  const n = data.length;
  const pts = data.map((v, i) => {
    if (v == null) return null;
    const x = (i / (n - 1)) * (w - 4) + 2;
    const y = height - 2 - ((v - min) / range) * (height - 4);
    return [x, y];
  });
  const firstIdx = pts.findIndex(p => p);
  let d = "";
  let lastIdx = -1;
  pts.forEach((p, i) => {
    if (!p) return;
    d += (lastIdx < 0 ? `M${p[0]},${p[1]}` : ` L${p[0]},${p[1]}`);
    lastIdx = i;
  });
  const last = pts[lastIdx];
  const fillPath = firstIdx >= 0 && last
    ? `${d} L${last[0]},${height} L${pts[firstIdx][0]},${height} Z`
    : "";
  return (
    <div ref={ref} style={{ width: "100%", height }}>
      <svg className="sparkline" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none" width="100%" height={height}>
        {fill && <path d={fillPath} fill={color} opacity="0.12" />}
        <path d={d} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" />
        {last && <circle cx={last[0]} cy={last[1]} r="2.5" fill={color} />}
      </svg>
    </div>
  );
}

function BranchChip({ branch, size = "sm" }) {
  if (!branch) return null;
  const pad = size === "xs" ? "2px 5px" : "3px 6px";
  const fs = size === "xs" ? 10 : 11;
  return (
    <span className="chip" style={{ background: branch.hex, color: "white", padding: pad, fontSize: fs, borderRadius: 4, fontFamily: "var(--font-mono)", fontWeight: 700, letterSpacing: "0.06em" }}>
      {branch.code}
    </span>
  );
}

function Ring({ value, target, size = 70, stroke = 7, color = "var(--raudhah-pink)", track = "var(--panel-sunken)", label = true }) {
  const pct = Math.min(1.2, value / target);
  const pctDisplay = Math.round((value / target) * 100);
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const offset = c * (1 - Math.min(1, pct));
  return (
    <div className="ring" style={{ width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} stroke={track} strokeWidth={stroke} fill="none" />
        <circle cx={size/2} cy={size/2} r={r} stroke={color} strokeWidth={stroke} fill="none"
                strokeDasharray={c} strokeDashoffset={offset} strokeLinecap="round"
                style={{ transition: "stroke-dashoffset 700ms var(--ease-out)" }}/>
      </svg>
      {label && (
        <div className="ring-label">
          <div style={{ fontSize: size * 0.24, color: "var(--fg1)" }}>{pctDisplay}%</div>
        </div>
      )}
    </div>
  );
}

function Bullet({ label, value, target, target2, color = "var(--raudhah-pink)", unit = "", onClick }) {
  const max = Math.max(target2 || 0, target, value) * 1.05;
  const pct = (value / max) * 100;
  const tickPct = (target / max) * 100;
  const tick2Pct = target2 ? (target2 / max) * 100 : null;
  const hit = value >= target;
  return (
    <div className="bullet" onClick={onClick} style={{ cursor: onClick ? "pointer" : "default" }}>
      <div className="bullet-head">
        <span className="lbl">{label}</span>
        <span className="val">
          <b>{value.toLocaleString()}</b> <span style={{ opacity: 0.5 }}>/ {target.toLocaleString()}{unit}</span>
          {" "}
          <span className={"pill " + (hit ? "ok" : "warn")} style={{ marginLeft: 6, padding: "1px 6px", fontSize: 10 }}>
            <span className="d"></span>
            {hit ? "HIT" : Math.round((value/target)*100) + "%"}
          </span>
        </span>
      </div>
      <div className="bar">
        <div className="fill" style={{ width: Math.min(100, pct) + "%", background: color }} />
        <div className="tick" style={{ left: `calc(${tickPct}% - 1px)` }} />
        {tick2Pct && <div className="tick" style={{ left: `calc(${tick2Pct}% - 1px)`, opacity: 0.35 }} />}
      </div>
    </div>
  );
}

function Delta({ value, pct, unit = "", inverse = false }) {
  const up = value > 0;
  const flat = value === 0;
  const cls = flat ? "flat" : (up ? (inverse ? "down" : "up") : (inverse ? "up" : "down"));
  const arrow = flat ? "—" : (up ? "▲" : "▼");
  return (
    <span className={"delta " + cls}>
      {arrow} {up ? "+" : ""}{value.toLocaleString()}{unit}
      {pct != null && <span style={{ opacity: 0.7 }}> {pct > 0 ? "+" : ""}{pct}%</span>}
    </span>
  );
}

function StatusPill({ kind, children }) {
  return (
    <span className={"pill " + kind}>
      <span className="d"></span>
      {children}
    </span>
  );
}

Object.assign(window, { Sparkline, BranchChip, Ring, Bullet, Delta, StatusPill });
