// Shared atoms: Icons, Chip, formatters — exposed globally for other Babel scripts
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Icons (lucide-inspired, original strokes) ----------
const Icon = {
  Dashboard: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><rect x="3" y="3" width="7" height="9" rx="2"/><rect x="14" y="3" width="7" height="5" rx="2"/><rect x="14" y="12" width="7" height="9" rx="2"/><rect x="3" y="16" width="7" height="5" rx="2"/></svg>),
  Box: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M21 8 12 3 3 8v8l9 5 9-5V8z"/><path d="M3 8l9 5 9-5"/><path d="M12 13v8"/></svg>),
  Move: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/><path d="M5 5v14"/></svg>),
  Sparkle: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 3v4M12 17v4M3 12h4M17 12h4M6.3 6.3l2.8 2.8M14.9 14.9l2.8 2.8M6.3 17.7l2.8-2.8M14.9 9.1l2.8-2.8"/></svg>),
  Chart: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 3v18h18"/><path d="M7 14l3-3 4 4 5-6"/></svg>),
  Gear: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.9.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.9 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.9.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.9-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9V9c.3.6.9 1 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>),
  Search: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>),
  Plus: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 5v14M5 12h14"/></svg>),
  Minus: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M5 12h14"/></svg>),
  Bell: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10 21a2 2 0 0 0 4 0"/></svg>),
  Flag: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M4 21V5a1 1 0 0 1 .6-.9C5.3 3.8 7 3 9 3c3 0 4 2 7 2 1.7 0 3.4-.7 4-1V14c-.6.3-2.3 1-4 1-3 0-4-2-7-2-1.5 0-2.7.5-3.5 1"/></svg>),
  Trash: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M10 11v6M14 11v6"/></svg>),
  Edit: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M17 3a2.8 2.8 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z"/></svg>),
  More: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="5" cy="12" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="19" cy="12" r="1.5"/></svg>),
  Check: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M20 6 9 17l-5-5"/></svg>),
  X: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M18 6 6 18M6 6l12 12"/></svg>),
  ArrowDown: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 5v14M5 12l7 7 7-7"/></svg>),
  ArrowUp: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 19V5M5 12l7-7 7 7"/></svg>),
  ArrowRight: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M5 12h14M13 5l7 7-7 7"/></svg>),
  ArrowLeft: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M19 12H5M11 5l-7 7 7 7"/></svg>),
  Warning: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg>),
  AlertCircle: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>),
  InfoCircle: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>),
  Trend: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 17 10 10l4 4 7-7"/><path d="M14 7h7v7"/></svg>),
  Truck: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M1 7h13v10H1z"/><path d="M14 10h4l3 3v4h-7z"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="17.5" cy="18.5" r="2.5"/></svg>),
  Globe: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/></svg>),
  User: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>),
  Tag: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 3h9l9 9-9 9-9-9z"/><circle cx="8" cy="8" r="1.5"/></svg>),
  Filter: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 4h18l-7 9v6l-4 2v-8z"/></svg>),
  Download: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 3v12M7 10l5 5 5-5"/><path d="M5 21h14"/></svg>),
  Print: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M6 9V3h12v6M6 18h12v4H6z"/><rect x="3" y="9" width="18" height="9" rx="2"/></svg>),
  Folder: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M3 6a2 2 0 0 1 2-2h4l2 3h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>),
  Layers: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 2 2 7l10 5 10-5z"/><path d="M2 12l10 5 10-5"/><path d="M2 17l10 5 10-5"/></svg>),
  Clock: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>),
  Receive: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 3v12"/><path d="M6 9l6 6 6-6"/><path d="M5 21h14"/></svg>),
  Issue: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M12 21V9"/><path d="M6 15l6-6 6 6"/><path d="M5 3h14"/></svg>),
  Adjust: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M4 6h13M4 12h9M4 18h13"/><circle cx="19" cy="6" r="2"/><circle cx="16" cy="12" r="2"/><circle cx="19" cy="18" r="2"/></svg>),
  Sun: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>),
  Moon: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>),
  Map: (p) => (<svg className="icon" viewBox="0 0 24 24" {...p}><path d="m3 6 6-3 6 3 6-3v15l-6 3-6-3-6 3z"/><path d="M9 3v15M15 6v15"/></svg>)
};

// ---------- Formatters ----------
function fmtThousands(n, decimals = 0) {
  if (n == null || isNaN(n)) return '—';
  return Number(n).toLocaleString('en-US', { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
}
function fmtCurrency(n) {
  if (n == null || isNaN(n)) return '—';
  return Number(n).toLocaleString('en-US', { maximumFractionDigits: 0 });
}
function fmtDate(s, lang) {
  if (!s) return '—';
  const d = new Date(s);
  if (lang === 'th') {
    return d.toLocaleDateString('th-TH', { day: '2-digit', month: 'short' });
  }
  return d.toLocaleDateString('en-US', { day: '2-digit', month: 'short' });
}
function daysSince(s) {
  if (!s) return null;
  const d = new Date(s);
  const today = new Date('2026-04-01'); // simulate "now" after March data
  return Math.max(0, Math.floor((today - d) / 86400000));
}

// ---------- Chip / Pill ----------
function StatusPill({ status, t }) {
  const label = t['status_' + status] || status;
  return <span className={"pill pill-" + status}>{label}</span>;
}

function ABCBadge({ abc }) {
  return <span className={"abc abc-" + abc}>{abc}</span>;
}

// ---------- Sparkline ----------
function Sparkline({ data, color }) {
  if (!data || !data.length) return null;
  const max = Math.max(...data, 1);
  const min = 0;
  const w = 90, h = 28;
  const step = w / Math.max(data.length - 1, 1);
  const pts = data.map((v, i) => `${(i*step).toFixed(1)},${(h - (v-min)/(max-min) * (h-4) - 2).toFixed(1)}`).join(' ');
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${h}`}>
      <polyline points={pts} fill="none" stroke={color || 'var(--accent)'} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

// ---------- Pie / donut chart ----------
function PieChart({ slices, hovered, setHovered, centerLabel, size = 200, thickness = 38, unit }) {
  const total = slices.reduce((s, x) => s + (x.value || 0), 0) || 1;
  const r = size / 2;
  const inner = r - thickness;
  let acc = 0;
  // For a 100% single slice, render as a full ring instead of arc (which would degenerate)
  const onlyOne = slices.filter(s => s.value > 0).length === 1;
  return (
    <div style={{ position: 'relative', width: size, height: size, flex: '0 0 ' + size + 'px' }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ overflow: 'visible' }}>
        {onlyOne && (
          <g>
            <circle cx={r} cy={r} r={(r + inner) / 2} fill="none" stroke={slices.find(s => s.value > 0)?.color || 'var(--accent)'} strokeWidth={thickness} />
          </g>
        )}
        {!onlyOne && slices.map((s, i) => {
          if (!s.value) return null;
          const startAngle = (acc / total) * Math.PI * 2 - Math.PI / 2;
          acc += s.value;
          const endAngle = (acc / total) * Math.PI * 2 - Math.PI / 2;
          const isHover = hovered === i;
          const dim = hovered != null && hovered !== i;
          // outer radius slightly bigger on hover
          const ro = r + (isHover ? 4 : 0);
          const ri = inner - (isHover ? 0 : 0);
          const x1 = r + ro * Math.cos(startAngle);
          const y1 = r + ro * Math.sin(startAngle);
          const x2 = r + ro * Math.cos(endAngle);
          const y2 = r + ro * Math.sin(endAngle);
          const xi1 = r + ri * Math.cos(endAngle);
          const yi1 = r + ri * Math.sin(endAngle);
          const xi2 = r + ri * Math.cos(startAngle);
          const yi2 = r + ri * Math.sin(startAngle);
          const large = endAngle - startAngle > Math.PI ? 1 : 0;
          const d = [
            `M ${x1} ${y1}`,
            `A ${ro} ${ro} 0 ${large} 1 ${x2} ${y2}`,
            `L ${xi1} ${yi1}`,
            `A ${ri} ${ri} 0 ${large} 0 ${xi2} ${yi2}`,
            'Z'
          ].join(' ');
          return (
            <path
              key={i}
              d={d}
              fill={s.color}
              opacity={dim ? 0.35 : 1}
              style={{ transition: 'opacity .15s, d .15s', cursor: 'pointer' }}
              onMouseEnter={() => setHovered && setHovered(i)}
              onMouseLeave={() => setHovered && setHovered(null)}
            />
          );
        })}
      </svg>
      {centerLabel && (
        <div style={{
          position: 'absolute', inset: 0,
          display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
          pointerEvents: 'none', textAlign: 'center'
        }}>
          <div style={{ fontSize: 22, fontWeight: 700, lineHeight: 1, fontVariantNumeric: 'tabular-nums' }}>{centerLabel.primary}</div>
          {unit && <div className="t-muted" style={{ fontSize: 11, marginTop: 3 }}>{unit}</div>}
          <div className="t-muted" style={{ fontSize: 11.5, marginTop: 4, maxWidth: size - thickness*2 - 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{centerLabel.secondary}</div>
        </div>
      )}
    </div>
  );
}


function useOutsideClick(ref, onOutside) {
  useEffect(() => {
    function handler(e) {
      if (ref.current && !ref.current.contains(e.target)) onOutside();
    }
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [ref, onOutside]);
}

// ---------- Toast system ----------
const ToastContext = React.createContext(null);
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg, kind = 'ok') => {
    const id = Math.random().toString(36).slice(2);
    setToasts(t => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 2400);
  }, []);
  return (
    <ToastContext.Provider value={push}>
      {children}
      <div className="toast-wrap">
        {toasts.map(t => (
          <div key={t.id} className={"toast " + t.kind}>
            {t.kind === 'ok' && <Icon.Check className="icon icon-sm" />}
            {t.kind === 'bad' && <Icon.X className="icon icon-sm" />}
            <span>{t.msg}</span>
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}
function useToast() { return React.useContext(ToastContext); }

// ---------- Category labels ----------
function catLabel(cat, t) {
  return t['cat_' + cat] || cat;
}

// Generate sparkline data from monthlyDemand
function genSpark(product) {
  const base = product.monthlyDemand / 30;
  const arr = [];
  let seed = 0;
  for (let i = 0; i < product.sku.length; i++) seed = (seed * 31 + product.sku.charCodeAt(i)) >>> 0;
  for (let i = 0; i < 12; i++) {
    seed = (seed * 1664525 + 1013904223) >>> 0;
    const v = base * (0.4 + (seed % 1000) / 800);
    arr.push(v);
  }
  return arr;
}

Object.assign(window, {
  Icon, fmtThousands, fmtCurrency, fmtDate, daysSince,
  StatusPill, ABCBadge, Sparkline, PieChart,
  useOutsideClick, ToastProvider, useToast,
  catLabel, genSpark
});
