// ============================================================
// components.jsx — Shared UI primitives + icons
// ============================================================

const { useState, useEffect, useRef, useMemo, useCallback, createContext, useContext } = React;

// ============ Icons (inline SVG, hairline) ============
const Icon = ({ name, size = 16, className = "", strokeWidth = 1.6 }) => {
  const props = {
    width: size, height: size, viewBox: "0 0 24 24",
    fill: "none", stroke: "currentColor", strokeWidth, strokeLinecap: "round", strokeLinejoin: "round",
    className,
  };
  switch (name) {
    case "dashboard": return <svg {...props}><rect x="3" y="3" width="7" height="9"/><rect x="14" y="3" width="7" height="5"/><rect x="14" y="12" width="7" height="9"/><rect x="3" y="16" width="7" height="5"/></svg>;
    case "receive": return <svg {...props}><path d="M12 3v12"/><path d="m7 10 5 5 5-5"/><path d="M5 21h14"/></svg>;
    case "issue": return <svg {...props}><path d="M12 21V9"/><path d="m7 14 5-5 5 5"/><path d="M5 3h14"/></svg>;
    case "package": return <svg {...props}><path d="m7.5 4.27 9 5.15"/><path d="M21 8 12 3 3 8l9 5 9-5Z"/><path d="M3 8v8l9 5 9-5V8"/><path d="M12 13v8"/></svg>;
    case "warehouse": return <svg {...props}><path d="M22 8.35V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8.35a2 2 0 0 1 1.26-1.86L12 3l8.74 3.49A2 2 0 0 1 22 8.35Z"/><path d="M6 18h12"/><path d="M6 14h12"/><path d="M6 10h12"/></svg>;
    case "chart": return <svg {...props}><path d="M3 3v18h18"/><path d="m7 14 4-4 4 4 5-5"/></svg>;
    case "activity": return <svg {...props}><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>;
    case "users": return <svg {...props}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>;
    case "user": return <svg {...props}><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>;
    case "search": return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>;
    case "plus": return <svg {...props}><path d="M12 5v14"/><path d="M5 12h14"/></svg>;
    case "minus": return <svg {...props}><path d="M5 12h14"/></svg>;
    case "close": case "x": return <svg {...props}><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>;
    case "check": return <svg {...props}><path d="M20 6 9 17l-5-5"/></svg>;
    case "edit": return <svg {...props}><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z"/></svg>;
    case "trash": return <svg {...props}><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"/></svg>;
    case "arrow-up": return <svg {...props}><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>;
    case "arrow-down": return <svg {...props}><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></svg>;
    case "arrow-right": return <svg {...props}><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>;
    case "arrow-left": return <svg {...props}><path d="M19 12H5"/><path d="m12 19-7-7 7-7"/></svg>;
    case "barcode": return <svg {...props}><path d="M3 5v14"/><path d="M8 5v14"/><path d="M12 5v14"/><path d="M17 5v14"/><path d="M21 5v14"/></svg>;
    case "filter": return <svg {...props}><path d="M22 3H2l8 9.46V19l4 2v-8.54Z"/></svg>;
    case "alert": return <svg {...props}><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>;
    case "info": return <svg {...props}><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>;
    case "settings": return <svg {...props}><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2Z"/><circle cx="12" cy="12" r="3"/></svg>;
    case "logout": return <svg {...props}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/></svg>;
    case "bell": return <svg {...props}><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>;
    case "calendar": return <svg {...props}><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4"/><path d="M8 2v4"/><path d="M3 10h18"/></svg>;
    case "download": return <svg {...props}><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/></svg>;
    case "eye": return <svg {...props}><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>;
    case "more": return <svg {...props}><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>;
    case "scan": return <svg {...props}><path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><path d="M7 12h10"/></svg>;
    case "loader": return <svg {...props}><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>;
    default: return null;
  }
};

// ============ Toast system ============
const ToastContext = createContext(null);

function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const idRef = useRef(0);
  const push = useCallback((msg, type = "success") => {
    const id = ++idRef.current;
    setToasts(prev => [...prev, { id, msg, type }]);
    setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 3200);
  }, []);
  return (
    <ToastContext.Provider value={push}>
      {children}
      <div className="toast-stack">
        {toasts.map(t => (
          <div key={t.id} className={`toast ${t.type}`}>
            <Icon name={t.type === "success" ? "check" : t.type === "danger" ? "alert" : "info"} size={16} className="toast-ico"/>
            <span>{t.msg}</span>
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}
const useToast = () => useContext(ToastContext);

// ============ Animated counter ============
function AnimatedNumber({ value, duration = 900, format = (n) => Math.round(n).toLocaleString("th-TH"), prefix = "", suffix = "" }) {
  const [n, setN] = useState(value);
  const fromRef = useRef(value);
  useEffect(() => {
    const from = fromRef.current;
    const to = value;
    if (from === to) return;
    const start = performance.now();
    let raf;
    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      const eased = 1 - Math.pow(1 - t, 3);
      const cur = from + (to - from) * eased;
      setN(cur);
      if (t < 1) raf = requestAnimationFrame(tick);
      else fromRef.current = to;
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [value, duration]);
  return <span className="tnum">{prefix}{format(n)}{suffix}</span>;
}

// ============ Modal ============
function Modal({ open, onClose, title, children, footer, size = "md" }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose && onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className={`modal ${size === "lg" ? "modal-lg" : ""}`} onClick={(e) => e.stopPropagation()}>
        <div className="modal-header">
          <div className="modal-title">{title}</div>
          <button className="btn btn-ghost btn-icon" onClick={onClose}><Icon name="x" size={16}/></button>
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-footer">{footer}</div>}
      </div>
    </div>
  );
}

// ============ Badge helpers ============
function StockBadge({ qty, reorderPoint }) {
  if (qty <= 0) return <span className="badge badge-danger"><span className="badge-dot"/>หมดสต๊อก</span>;
  if (qty < reorderPoint) return <span className="badge badge-warn"><span className="badge-dot"/>ต่ำกว่าจุดสั่งซื้อ</span>;
  return <span className="badge badge-success"><span className="badge-dot"/>พร้อมจำหน่าย</span>;
}

function MovementBadge({ type }) {
  if (type === "receive") return <span className="badge badge-success"><Icon name="arrow-down" size={11}/>รับเข้า</span>;
  if (type === "issue") return <span className="badge badge-danger"><Icon name="arrow-up" size={11}/>จ่ายออก</span>;
  if (type === "transfer") return <span className="badge badge-accent"><Icon name="arrow-right" size={11}/>ย้าย</span>;
  if (type === "adjust") return <span className="badge"><Icon name="edit" size={11}/>ปรับ</span>;
  return <span className="badge">{type}</span>;
}

function RoleBadge({ role }) {
  if (role === "admin") return <span className="badge badge-accent">Admin</span>;
  return <span className="badge">User</span>;
}

// ============ Barcode scan modal ============
function BarcodeScanModal({ open, onClose, products, onScan }) {
  const [manual, setManual] = useState("");
  const [recent] = useState(() => products.slice(0, 4));

  // Auto fire fake scan after 2.4s if open
  useEffect(() => {
    if (!open) return;
    setManual("");
    const t = setTimeout(() => {
      const fakeIdx = Math.floor(Math.random() * products.length);
      const p = products[fakeIdx];
      onScan(p);
    }, 2400);
    return () => clearTimeout(t);
  }, [open, products, onScan]);

  const handleManual = (e) => {
    e.preventDefault();
    if (!manual.trim()) return;
    const p = products.find(x => x.barcode === manual.trim() || x.sku.toLowerCase() === manual.trim().toLowerCase());
    if (p) onScan(p);
    else alert("ไม่พบสินค้าที่ตรงกับบาร์โค้ด/SKU นี้");
  };

  return (
    <Modal open={open} onClose={onClose} title="สแกนบาร์โค้ดสินค้า" size="lg">
      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 20 }}>
        <div>
          <div className="scan-frame">
            <div className="scan-fake-product">CAMERA · 1080p · LIVE</div>
            <div className="scan-corners"><i/></div>
            <div className="scan-line"/>
          </div>
          <div style={{ marginTop: 12, display: "flex", alignItems: "center", gap: 8, fontSize: 12, color: "var(--fg-3)" }}>
            <span className="pulse-dot"/>
            กำลังค้นหาบาร์โค้ด... (จะตรวจพบใน ~2 วินาที)
          </div>
        </div>
        <div>
          <form onSubmit={handleManual} className="field">
            <label className="label">หรือกรอกบาร์โค้ด/SKU ด้วยตนเอง</label>
            <div className="input-with-prefix">
              <Icon name="barcode" size={14} className="input-prefix"/>
              <input className="input" placeholder="8851234500011 หรือ MLK-001" value={manual} onChange={e => setManual(e.target.value)} autoFocus/>
            </div>
            <button type="submit" className="btn btn-accent" style={{ marginTop: 8 }}>
              <Icon name="check" size={14}/> ยืนยัน
            </button>
          </form>
          <div style={{ marginTop: 18 }}>
            <div className="text-xs uppercase muted" style={{ marginBottom: 8 }}>สแกนล่าสุด</div>
            <div className="col" style={{ gap: 6 }}>
              {recent.map(p => (
                <button key={p.sku} className="nav-item" style={{ padding: 8 }} onClick={() => onScan(p)}>
                  <Icon name="package" size={14}/>
                  <div style={{ flex: 1, textAlign: "left" }}>
                    <div style={{ fontSize: 12.5, fontWeight: 500 }}>{p.name}</div>
                    <div className="mono text-xs muted">{p.sku} · {p.barcode}</div>
                  </div>
                </button>
              ))}
            </div>
          </div>
        </div>
      </div>
    </Modal>
  );
}

// ============ Empty state ============
function EmptyState({ icon = "package", title, sub }) {
  return (
    <div className="empty-state">
      <Icon name={icon} size={32} className="empty-state-ico"/>
      <div style={{ fontWeight: 500, color: "var(--fg-2)", fontSize: 14 }}>{title}</div>
      {sub && <div style={{ marginTop: 4, fontSize: 12.5 }}>{sub}</div>}
    </div>
  );
}

// ============ Confirm dialog ============
function ConfirmDialog({ open, title, message, danger, onConfirm, onClose }) {
  return (
    <Modal open={open} onClose={onClose} title={title} footer={
      <>
        <button className="btn btn-secondary" onClick={onClose}>ยกเลิก</button>
        <button className={`btn ${danger ? "btn-danger" : "btn-primary"}`} onClick={() => { onConfirm(); onClose(); }}>ยืนยัน</button>
      </>
    }>
      <div style={{ color: "var(--fg-2)", fontSize: 13.5 }}>{message}</div>
    </Modal>
  );
}

Object.assign(window, {
  Icon, ToastProvider, useToast, AnimatedNumber,
  Modal, ConfirmDialog, BarcodeScanModal,
  StockBadge, MovementBadge, RoleBadge, EmptyState,
});
