/* ===========================================================
   Reiktable — shared UI primitives + icons
   Exposes (window): Icon, Btn, Modal, Confirm, Field, NumIn,
   Tabs, PillTabs, Tag, Avatar, Empty, Spinner, helpers
   =========================================================== */
(function () {
  const { useState, useEffect, useRef } = React;

  // ---------------- icons ----------------
  const P = (d, extra) => <path d={d} {...(extra || {})} />;
  const ICONS = {
    grid: <><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></>,
    users: <><circle cx="9" cy="8" r="3.4"/><path d="M3 20c0-3.3 2.7-5 6-5s6 1.7 6 5"/><path d="M16 5.2a3.4 3.4 0 010 5.6M17 15c2.7.4 4 2.2 4 5"/></>,
    book: <><path d="M4 5a2 2 0 012-2h13v16H6a2 2 0 00-2 2z"/><path d="M8 7h7M8 11h5"/></>,
    dice: <><rect x="3" y="3" width="18" height="18" rx="3"/><circle cx="8" cy="8" r="1.3" fill="currentColor" stroke="none"/><circle cx="16" cy="16" r="1.3" fill="currentColor" stroke="none"/><circle cx="16" cy="8" r="1.3" fill="currentColor" stroke="none"/><circle cx="8" cy="16" r="1.3" fill="currentColor" stroke="none"/></>,
    sword: <><path d="M14.5 4L20 4l0 5.5L9.5 20 4 20l0-5.5z" /><path d="M5 14l5 5M14.5 9.5L9 15"/></>,
    journal: <><path d="M4 4h16v13H7l-3 3z"/><path d="M8 8h8M8 12h6"/></>,
    skull: <><path d="M12 3a8 8 0 00-8 8c0 3 1.5 4.5 1.5 6.5V19a1 1 0 001 1h11a1 1 0 001-1v-1.5C19 15.5 20 14 20 11a8 8 0 00-8-8z"/><circle cx="9" cy="11" r="1.6"/><circle cx="15" cy="11" r="1.6"/><path d="M11 20v-3M13 20v-3"/></>,
    sparkles: <><path d="M12 3l1.6 4.4L18 9l-4.4 1.6L12 15l-1.6-4.4L6 9l4.4-1.6z"/><path d="M18 14l.8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8z"/></>,
    map: <><path d="M9 4L3 6v14l6-2 6 2 6-2V4l-6 2z"/><path d="M9 4v14M15 6v14"/></>,
    flag: <><path d="M5 21V4M5 4h12l-2 4 2 4H5"/></>,
    edit: <><path d="M12 20h9M16 4l4 4-11 11-4 1 1-4z"/></>,
    plus: <><path d="M12 5v14M5 12h14"/></>,
    trash: <><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></>,
    x: <><path d="M6 6l12 12M18 6L6 18"/></>,
    search: <><circle cx="11" cy="11" r="7"/><path d="M21 21l-4-4"/></>,
    upload: <><path d="M12 16V4M7 9l5-5 5 5"/><path d="M5 20h14"/></>,
    download: <><path d="M12 4v12M7 11l5 5 5-5"/><path d="M5 20h14"/></>,
    check: <><path d="M5 12l5 5L20 6"/></>,
    chevR: <><path d="M9 6l6 6-6 6"/></>,
    chevD: <><path d="M6 9l6 6 6-6"/></>,
    menu: <><path d="M4 6h16M4 12h16M4 18h16"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 13.5a7.8 7.8 0 000-3l2-1.5-2-3.4-2.3 1a7.6 7.6 0 00-2.6-1.5L14 0h-4l-.5 2.6a7.6 7.6 0 00-2.6 1.5l-2.3-1-2 3.4 2 1.5a7.8 7.8 0 000 3l-2 1.5 2 3.4 2.3-1a7.6 7.6 0 002.6 1.5L10 24h4l.5-2.6a7.6 7.6 0 002.6-1.5l2.3 1 2-3.4z"/></>,
    shield: <><path d="M12 3l7 3v5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6z"/></>,
    heart: <><path d="M12 20S4 14.5 4 8.8A4.2 4.2 0 0112 6a4.2 4.2 0 018 2.8C20 14.5 12 20 12 20z"/></>,
    bolt: <><path d="M13 2L4 14h7l-1 8 9-12h-7z"/></>,
    coin: <><ellipse cx="12" cy="7" rx="8" ry="3.4"/><path d="M4 7v6c0 1.9 3.6 3.4 8 3.4s8-1.5 8-3.4V7"/><path d="M4 13c0 1.9 3.6 3.4 8 3.4s8-1.5 8-3.4"/></>,
    star: <><path d="M12 3l2.6 5.6L21 9.3l-4.5 4.3 1.1 6.4L12 17l-5.6 3 1.1-6.4L3 9.3l6.4-.7z"/></>,
    send: <><path d="M4 12l16-8-7 16-2-6z"/><path d="M11 14l9-10"/></>,
    eye: <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="2.6"/></>,
    pin: <><path d="M12 2l2.5 5 5.5.8-4 4 1 5.4L12 19.7 7 17.2l1-5.4-4-4 5.5-.8z"/></>,
    drop: <><path d="M12 3s6 6.5 6 11a6 6 0 01-12 0c0-4.5 6-11 6-11z"/></>,
    swords: <><path d="M3 3l7 7M3 7V3h4M21 3l-7 7M21 7V3h-4M10 14l-2 2 2 2 2-2M14 14l2 2-2 2-2-2"/></>,
    file: <><path d="M6 2h8l4 4v16H6z"/><path d="M14 2v4h4"/></>,
    refresh: <><path d="M4 12a8 8 0 0114-5l2 2M20 12a8 8 0 01-14 5l-2-2"/><path d="M20 4v5h-5M4 20v-5h5"/></>,
    clock: <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    paw: <><ellipse cx="7" cy="9" rx="1.6" ry="2.2"/><ellipse cx="12" cy="7.5" rx="1.6" ry="2.4"/><ellipse cx="17" cy="9" rx="1.6" ry="2.2"/><path d="M12 12c-3 0-5 2-5 4.2C7 18 9 19 12 19s5-1 5-2.8C17 14 15 12 12 12z"/></>,
  };
  window.Icon = function ({ name, size = 18, className, style, fill }) {
    const body = ICONS[name] || ICONS.grid;
    return (
      <svg width={size} height={size} viewBox="0 0 24 24" fill={fill || "none"}
        stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"
        className={className} style={style}>{body}</svg>
    );
  };

  // ---------------- helpers ----------------
  window.cls = (...a) => a.filter(Boolean).join(" ");
  window.coin = (w) => {
    if (!w) return "0 bp";
    const parts = [];
    if (w.gc) parts.push(`${w.gc} GC`);
    if (w.ss) parts.push(`${w.ss} ss`);
    if (w.bp) parts.push(`${w.bp} bp`);
    return parts.join(" · ") || "0 bp";
  };
  window.initials = (n) => (n || "?").split(/\s+/).map(w => w[0]).slice(0, 2).join("").toUpperCase();

  // ---------------- Btn ----------------
  window.Btn = function ({ icon, children, className, ...rest }) {
    return (
      <button className={cls("btn", className)} {...rest}>
        {icon && <Icon name={icon} size={15} />}{children}
      </button>
    );
  };

  // ---------------- Tag ----------------
  window.Tag = function ({ children, kind, onRemove, className }) {
    return (
      <span className={cls("tag", kind, className)}>
        {children}
        {onRemove && <span className="x" onClick={onRemove}><Icon name="x" size={11} /></span>}
      </span>
    );
  };

  // ---------------- Avatar ----------------
  window.Avatar = function ({ name, color, img, size = "md" }) {
    const style = img
      ? { backgroundImage: `url(${img})` }
      : { background: color ? `linear-gradient(140deg, ${color}, ${color}99)` : "var(--raise)", color: "#fff" };
    return <div className={cls("ava", size)} style={style}>{!img && initials(name)}</div>;
  };

  // ---------------- Modal ----------------
  window.Modal = function ({ title, icon, onClose, children, footer, size }) {
    useEffect(() => {
      const h = e => { if (e.key === "Escape") onClose && onClose(); };
      window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h);
    }, []);
    return (
      <div className="modal-back" onMouseDown={e => { if (e.target === e.currentTarget) onClose && onClose(); }}>
        <div className={cls("modal", size)}>
          {title && (
            <div className="modal-h">
              {icon && <Icon name={icon} size={18} style={{ color: "var(--tx-3)" }} />}
              <h3>{title}</h3>
              <div className="sp"></div>
              <button className="btn icon ghost" onClick={onClose}><Icon name="x" size={16} /></button>
            </div>
          )}
          <div className="modal-b">{children}</div>
          {footer && <div className="modal-f">{footer}</div>}
        </div>
      </div>
    );
  };

  // ---------------- Confirm ----------------
  window.Confirm = function ({ title, body, danger, onYes, onClose, yes = "Confirm" }) {
    return (
      <Modal title={title} onClose={onClose} footer={<>
        <Btn className="ghost" onClick={onClose}>Cancel</Btn>
        <Btn className={danger ? "danger" : "pri"} onClick={() => { onYes(); onClose(); }}>{yes}</Btn>
      </>}>
        <p style={{ margin: 0, color: "var(--tx-2)" }}>{body}</p>
      </Modal>
    );
  };

  // ---------------- Field ----------------
  window.Field = function ({ label, children }) {
    return <label className="fld">{label && <span className="lbl">{label}</span>}{children}</label>;
  };

  // ---------------- NumIn (stepper) ----------------
  window.NumIn = function ({ value, onChange, min = -999, max = 9999, w = 64 }) {
    return (
      <input className="input num sm" style={{ width: w }} type="number" value={value}
        onChange={e => { let v = parseInt(e.target.value || "0", 10); if (isNaN(v)) v = 0; v = Math.max(min, Math.min(max, v)); onChange(v); }} />
    );
  };

  // ---------------- Tabs ----------------
  window.Tabs = function ({ tabs, active, onChange }) {
    return (
      <div className="tabs">
        {tabs.map(t => (
          <button key={t.k} className={cls("tab", active === t.k && "on")} onClick={() => onChange(t.k)}>{t.label}</button>
        ))}
      </div>
    );
  };
  window.PillTabs = function ({ tabs, active, onChange }) {
    return (
      <div className="pill-tabs">
        {tabs.map(t => (
          <button key={t.k} className={cls("pill", active === t.k && "on")} onClick={() => onChange(t.k)}>{t.label}</button>
        ))}
      </div>
    );
  };

  // ---------------- Empty ----------------
  window.Empty = function ({ icon = "grid", title, children }) {
    return <div className="empty"><Icon name={icon} size={40} /><h3>{title}</h3><div>{children}</div></div>;
  };

  // ---------------- Spinner ----------------
  window.Spinner = function ({ size = 16 }) {
    return <Icon name="refresh" size={size} className="spin" />;
  };
})();
