/* ui.jsx — shared primitives. Exports to window at end. */

/* ---- Icon: minimal line set ---- */
const ICONS = {
  heart: "M12 21s-7.5-4.6-10-9.3C.6 8.9 2 5.5 5.2 5.5c2 0 3.2 1.2 3.8 2.2.6-1 1.8-2.2 3.8-2.2 3.2 0 4.6 3.4 3.2 6.2C19.5 16.4 12 21 12 21z",
  star: "M12 3.2l2.5 5.6 6.1.6-4.6 4 1.4 6L12 16.9 6.6 19.4l1.4-6-4.6-4 6.1-.6z",
  check: "M5 12.5l4.2 4.3L19 7",
  x: "M6 6l12 12M18 6L6 18",
  wand: "M5 19l9-9M14 5l1.2 1.2M9 4l.6 1.6L11 6l-1.4.5L9 8l-.6-1.5L7 6l1.4-.4zM19 11l.5 1.3 1.3.5-1.3.5L19 15l-.5-1.4-1.3-.5 1.3-.5z",
  upload: "M12 16V4M7 9l5-5 5 5M5 20h14",
  cloud: "M7 18a4 4 0 010-8 5 5 0 019.6-1.3A3.5 3.5 0 0117 18z",
  plus: "M12 5v14M5 12h14",
  search: "M11 19a8 8 0 100-16 8 8 0 000 16zM21 21l-4-4",
  sliders: "M4 6h10M18 6h2M4 12h2M10 12h10M4 18h8M16 18h4M14 4v4M6 10v4M12 16v4",
  grid: "M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z",
  compare: "M4 5h7v14H4zM13 5h7v14h-7z",
  left: "M15 5l-7 7 7 7", right: "M9 5l7 7-7 7",
  close: "M6 6l12 12M18 6L6 18",
  camera: "M3 8a2 2 0 012-2h2l1.5-2h7L17 6h2a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2zM12 16a3.5 3.5 0 100-7 3.5 3.5 0 000 7z",
  folder: "M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z",
  image: "M3 5h18v14H3zM3 16l5-5 4 4 3-3 6 6",
  more: "M5 12h.01M12 12h.01M19 12h.01",
  info: "M12 21a9 9 0 100-18 9 9 0 000 18zM12 11v5M12 8h.01",
  sun: "M12 17a5 5 0 100-10 5 5 0 000 10zM12 1v3M12 20v3M4 12H1M23 12h-3M5 5l2 2M17 17l2 2M19 5l-2 2M7 17l-2 2",
  moon: "M21 12.8A8 8 0 0111.2 3 7 7 0 1021 12.8z",
  trash: "M4 7h16M9 7V5h6v2M6 7l1 13h10l1-13",
  user: "M12 12a4 4 0 100-8 4 4 0 000 8zM4 21a8 8 0 0116 0",
  sparkle: "M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z",
  message: "M21 12a8 8 0 01-11.5 7.2L4 21l1.8-5.5A8 8 0 1121 12z",
  download: "M12 4v12M7 11l5 5 5-5M5 20h14",
  send: "M22 2L11 13M22 2l-7 20-4-9-9-4z",
  layers: "M12 3l9 5-9 5-9-5zM3 14l9 5 9-5",
  eye: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12zM12 15a3 3 0 100-6 3 3 0 000 6z",
};

function Icon({ name, size = 18, fill = false, sw = 1.8, style, className }) {
  const d = ICONS[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" className={className} style={style}
      fill={fill ? "currentColor" : "none"} stroke="currentColor" strokeWidth={sw}
      strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d={d} />
    </svg>
  );
}

/* ---- Stars 1–5 ---- */
function Stars({ value = 0, onChange, size = 16, onLight = false, className = "" }) {
  const [hover, setHover] = React.useState(0);
  const interactive = !!onChange;
  return (
    <div className={"stars " + (onLight ? "stars-onlight " : "") + (interactive ? "interactive " : "") + className}
      onMouseLeave={() => setHover(0)} onClick={(e) => e.stopPropagation()}>
      {[1, 2, 3, 4, 5].map((n) => {
        const lit = (hover || value) >= n;
        return (
          <button key={n} className={"star" + (lit ? " lit" : "")} style={{ cursor: interactive ? "pointer" : "default" }}
            onMouseEnter={() => interactive && setHover(n)}
            onClick={() => interactive && onChange(n)} title={interactive ? n + " sao" : undefined}>
            <Icon name="star" size={size} fill={lit} sw={1.6} />
          </button>
        );
      })}
    </div>
  );
}

/* ---- Heart ---- */
function HeartBtn({ liked, onClick, floating = false }) {
  return (
    <button className={"heart-btn" + (liked ? " liked" : "")} onClick={(e) => { e.stopPropagation(); onClick(); }}
      title={liked ? "Bỏ yêu thích" : "Yêu thích"}>
      <Icon name="heart" size={17} fill={liked} sw={1.9} />
    </button>
  );
}

/* ---- Status pills (pick / edit / reject) ---- */
const STATUS_META = {
  pick: { ic: "check", label: "Chọn", cls: "on-pick" },
  reject: { ic: "x", label: "Bỏ", cls: "on-reject" },
};
function StatusRow({ status, onSet, show = ["pick", "reject"] }) {
  return (
    <div className="status-row" onClick={(e) => e.stopPropagation()}>
      {show.map((s) => (
        <button key={s} className={"spill" + (status === s ? " " + STATUS_META[s].cls : "")}
          onClick={() => onSet(s)} title={STATUS_META[s].label}>
          <Icon name={STATUS_META[s].ic} size={15} sw={2.1} />
        </button>
      ))}
    </div>
  );
}

/* ---- Modal ---- */
function Modal({ children, onClose, max = 440 }) {
  React.useEffect(() => {
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h); return () => window.removeEventListener("keydown", h);
  }, [onClose]);
  return (
    <div className="modal-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className="modal" style={{ maxWidth: max }}>{children}</div>
    </div>
  );
}

/* ---- Toast ---- */
const ToastCtx = React.createContext(() => {});
function ToastProvider({ children }) {
  const [toasts, setToasts] = React.useState([]);
  const push = React.useCallback((msg, ic = "check") => {
    const id = Math.random();
    setToasts((t) => [...t, { id, msg, ic }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2400);
  }, []);
  return (
    <ToastCtx.Provider value={push}>
      {children}
      <div className="toast-wrap">
        {toasts.map((t) => (
          <div key={t.id} className="toast"><Icon name={t.ic} size={16} className="t-ic" /> {t.msg}</div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
}
const useToast = () => React.useContext(ToastCtx);

/* ---- Avatar (initials) ---- */
function Avatar({ name, size = 30, role }) {
  const initials = (name || "?").split(" ").slice(-2).map((w) => w[0]).join("").toUpperCase();
  return (
    <div style={{
      width: size, height: size, borderRadius: "50%", display: "grid", placeItems: "center",
      background: role === "studio" ? "var(--accent)" : "var(--gold)",
      color: role === "studio" ? "#fff" : "oklch(0.3 0.05 70)", fontSize: size * 0.38, fontWeight: 800, flexShrink: 0,
    }}>{initials}</div>
  );
}

Object.assign(window, { Icon, Stars, HeartBtn, StatusRow, STATUS_META, Modal, ToastProvider, useToast, Avatar });
