// ===== Shared UI components for IDSS MBG =====
const { useState, useEffect, useMemo, useRef } = React;

// Inline SVG icons (stroke-based, monochrome)
const Icon = ({ name, size = 16 }) => {
  const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" };
  const paths = {
    dashboard: <><rect x="3" y="3" width="7" height="9" rx="1.2"/><rect x="14" y="3" width="7" height="5" rx="1.2"/><rect x="14" y="12" width="7" height="9" rx="1.2"/><rect x="3" y="16" width="7" height="5" rx="1.2"/></>,
    leaf: <><path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z"/><path d="M2 21c0-3 1.85-5.36 5.08-6"/></>,
    suppliers: <><path d="M3 7h18v10H3z"/><path d="M3 7l3-3h12l3 3"/><path d="M9 11h6"/></>,
    chart: <><path d="M3 3v18h18"/><path d="M7 14l4-4 4 3 5-7"/></>,
    menu: <><path d="M4 6h16"/><path d="M4 12h16"/><path d="M4 18h10"/></>,
    shield: <><path d="M12 3l8 3v5c0 5-3.5 9-8 10-4.5-1-8-5-8-10V6l8-3z"/><path d="M9 12l2 2 4-4"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></>,
    bell: <><path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.7 21a2 2 0 0 1-3.4 0"/></>,
    box: <><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.27 6.96L12 12.01l8.73-5.05"/><path d="M12 22.08V12"/></>,
    truck: <><rect x="1" y="6" width="14" height="11" rx="1"/><path d="M15 9h4l3 3v5h-7"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/></>,
    school: <><path d="M3 10l9-5 9 5"/><path d="M5 9v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9"/><path d="M10 19v-5h4v5"/></>,
    factory: <><path d="M3 21h18"/><path d="M5 21V9l5 4V9l5 4V5h4v16"/></>,
    user: <><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></>,
    arrow: <><path d="M5 12h14"/><path d="M13 6l6 6-6 6"/></>,
    download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></>,
    filter: <><path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3z"/></>,
    play: <><polygon points="6 3 20 12 6 21 6 3"/></>,
    refresh: <><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></>,
    lock: <><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
    logout: <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="M16 17l5-5-5-5"/><path d="M21 12H9"/></>
  };
  return <svg className="nav-icon" {...props} style={{ width: size, height: size }}>{paths[name]}</svg>;
};

// KPI card
const KPI = ({ label, value, unit, delta, deltaKind = "up", spark, intent }) => (
  <div className="kpi" style={intent === "primary" ? { background: "linear-gradient(180deg, var(--primary-50), var(--surface))", borderColor: "var(--primary-100)" } : null}>
    <div className="kpi-label">{label}</div>
    <div className="row" style={{ alignItems: "baseline", gap: 8, marginTop: 4 }}>
      <div className="kpi-value">{value}</div>
      {unit && <div className="kpi-unit">{unit}</div>}
    </div>
    {delta && <div className={`kpi-delta ${deltaKind}`}>{deltaKind === "up" ? "▲" : deltaKind === "down" ? "▼" : "•"} {delta}</div>}
    {spark && <div className="kpi-spark">{spark}</div>}
  </div>
);

// Sparkline
const Sparkline = ({ data, color = "var(--primary)", fill = true, height = 36 }) => {
  const w = 200, h = height;
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => [(i / (data.length - 1)) * w, h - ((v - min) / range) * (h - 4) - 2]);
  const path = pts.map((p, i) => (i === 0 ? "M" : "L") + p[0].toFixed(1) + "," + p[1].toFixed(1)).join(" ");
  const area = path + ` L${w},${h} L0,${h} Z`;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: "100%", height }}>
      {fill && <path d={area} fill={color} opacity="0.12"/>}
      <path d={path} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  );
};

// Bar mini
const BarMini = ({ value, max, kind = "" }) => (
  <div className={`bar ${kind}`}><span style={{ width: `${Math.min(100, (value / max) * 100)}%` }}/></div>
);

// Donut
const Donut = ({ value, max = 100, size = 72, stroke = 8, color = "var(--primary)", label }) => {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const p = Math.min(1, value / max);
  return (
    <div style={{ position: "relative", width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--line)" strokeWidth={stroke}/>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeDasharray={`${c*p} ${c}`} strokeLinecap="round"
          transform={`rotate(-90 ${size/2} ${size/2})`}/>
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", fontFamily: "var(--font-mono)", fontSize: 12, fontWeight: 600 }}>{label || `${Math.round(p*100)}%`}</div>
    </div>
  );
};

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

// Score input 1-5
const ScoreInput = ({ value, onChange }) => (
  <div className="row gap-xs">
    {[1,2,3,4,5].map(n => (
      <button key={n} onClick={() => onChange(n)}
        className={`score s${n}`}
        style={{
          opacity: value === n ? 1 : 0.35,
          outline: value === n ? "2px solid var(--ink-2)" : "none",
          border: 0, cursor: "pointer"
        }}>{n}</button>
    ))}
  </div>
);

// Pipeline stage chip row (EWS 6 tahap)
const Pipeline = ({ tahapan, hariIni, activeId, onPick }) => (
  <div className="pipe">
    {tahapan.map((t, i) => {
      const d = hariIni[t.id] || {};
      const skorAvg = (d.skor || []).reduce((a,b)=>a+b,0) / Math.max(1, (d.skor||[]).length);
      const led = skorAvg >= 4.3 ? "var(--accent)" : skorAvg >= 3.5 ? "var(--warn)" : "var(--danger)";
      return (
        <React.Fragment key={t.id}>
          <div className={`pipe-stage ${activeId === t.id ? "active" : ""}`} onClick={() => onPick && onPick(t.id)}>
            <span className="pipe-stage-led" style={{ background: led }}/>
            <div className="pipe-stage-num">T{t.idx} · {t.fase === "bahan" ? "Bahan" : "Jadi"}</div>
            <div className="pipe-stage-name">{t.nama}</div>
            <div className="pipe-stage-meta">{d.lulus || 0}/{d.batches || 0} batch · μ {skorAvg.toFixed(1)}</div>
          </div>
          {i < tahapan.length - 1 && <div className="pipe-divider">›</div>}
        </React.Fragment>
      );
    })}
  </div>
);

window.IDSSUI = { Icon, KPI, Sparkline, BarMini, Donut, Tabs, ScoreInput, Pipeline };
