// ==============================================
// Shared UI: Icons, Layout, ProductCard, Toast
// ==============================================
const { useState, useEffect, useMemo, useRef, useCallback, createContext, useContext } = React;

/* ----- ICONS (inline strokes, no external) ----- */
const Icon = ({ name, size = 18, className = "" }) => {
  const s = size;
  const common = {
    width: s, height: s, viewBox: "0 0 24 24", fill: "none",
    stroke: "currentColor", strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round",
    className
  };
  switch (name) {
    case "search":return <svg {...common}><circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" /></svg>;
    case "cart":return <svg {...common}><path d="M3 4h2l2.4 11.2a2 2 0 0 0 2 1.6h8.7a2 2 0 0 0 2-1.5L22 8H6" /><circle cx="9" cy="20" r="1.5" /><circle cx="18" cy="20" r="1.5" /></svg>;
    case "user":return <svg {...common}><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg>;
    case "phone":return <svg {...common}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" /></svg>;
    case "mail":return <svg {...common}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="m3 7 9 6 9-6" /></svg>;
    case "heart":return <svg {...common}><path d="M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1-1.1a5.5 5.5 0 0 0-7.8 7.8l1.1 1L12 21l7.7-7.7 1.1-1a5.5 5.5 0 0 0 0-7.8z" /></svg>;
    case "trash":return <svg {...common}><path d="M3 6h18" /><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /><path d="m19 6-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" /></svg>;
    case "plus":return <svg {...common}><path d="M12 5v14M5 12h14" /></svg>;
    case "minus":return <svg {...common}><path d="M5 12h14" /></svg>;
    case "x":return <svg {...common}><path d="M18 6 6 18M6 6l12 12" /></svg>;
    case "chevron-right":return <svg {...common}><path d="m9 18 6-6-6-6" /></svg>;
    case "chevron-down":return <svg {...common}><path d="m6 9 6 6 6-6" /></svg>;
    case "check":return <svg {...common}><path d="m5 12 5 5L20 7" /></svg>;
    case "download":return <svg {...common}><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 "print":return <svg {...common}><path d="M6 9V2h12v7" /><rect x="6" y="14" width="12" height="8" /><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" /></svg>;
    case "send":return <svg {...common}><path d="m22 2-7 20-4-9-9-4Z" /><path d="M22 2 11 13" /></svg>;
    case "file-text":return <svg {...common}><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><path d="M14 2v6h6" /><path d="M8 13h8M8 17h6" /></svg>;
    case "tag":return <svg {...common}><path d="M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0L2 12V2h10l8.6 8.6a2 2 0 0 1 0 2.8z" /><circle cx="7" cy="7" r="1" /></svg>;
    case "filter":return <svg {...common}><path d="M3 6h18M6 12h12M10 18h4" /></svg>;
    case "grid":return <svg {...common}><rect x="3" y="3" width="7" height="7" /><rect x="14" y="3" width="7" height="7" /><rect x="3" y="14" width="7" height="7" /><rect x="14" y="14" width="7" height="7" /></svg>;
    case "list":return <svg {...common}><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" /></svg>;
    case "package":return <svg {...common}><path d="m7.5 4.27 9 5.15M21 8 12 13 3 8m9 5v9" /><path d="M3 8v8l9 5 9-5V8l-9-5z" /></svg>;
    case "truck":return <svg {...common}><rect x="1" y="6" width="14" height="11" /><polygon points="15 9 22 9 22 17 15 17 15 9" /><circle cx="6" cy="20" r="2" /><circle cx="18" cy="20" r="2" /></svg>;
    case "shield":return <svg {...common}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" /></svg>;
    case "users":return <svg {...common}><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.87M16 3.13a4 4 0 0 1 0 7.75" /></svg>;
    case "trending-up":return <svg {...common}><polyline points="22 7 13.5 15.5 8.5 10.5 2 17" /><polyline points="16 7 22 7 22 13" /></svg>;
    case "dashboard":return <svg {...common}><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 "box":return <svg {...common}><path d="M21 8a2 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" /><polyline points="3.27 6.96 12 12.01 20.73 6.96" /><line x1="12" y1="22.08" x2="12" y2="12" /></svg>;
    case "log-out":return <svg {...common}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><polyline points="16 17 21 12 16 7" /><line x1="21" y1="12" x2="9" y2="12" /></svg>;
    case "log-in":return <svg {...common}><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" /><polyline points="10 17 15 12 10 7" /><line x1="15" y1="12" x2="3" y2="12" /></svg>;
    case "star":return <svg {...common} fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" /></svg>;
    case "edit":return <svg {...common}><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.12 2.12 0 0 1 3 3L12 15l-4 1 1-4z" /></svg>;
    case "settings":return <svg {...common}><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 0 2.83 2 2 0 0 1-2.83 0l-.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-2 2 2 2 0 0 1-2-2v-.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 0 2 2 0 0 1 0-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-2-2 2 2 0 0 1 2-2h.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 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.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 0 2 2 0 0 1 0 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 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" /></svg>;
    case "map-pin":return <svg {...common}><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" /></svg>;
    case "clock":return <svg {...common}><circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" /></svg>;
    case "menu":return <svg {...common}><line x1="3" y1="6" x2="21" y2="6" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="18" x2="21" y2="18" /></svg>;
    case "arrow-up":return <svg {...common}><path d="M12 19V5M5 12l7-7 7 7" /></svg>;
    case "arrow-down":return <svg {...common}><path d="M12 5v14M5 12l7 7 7-7" /></svg>;
    case "image":return <svg {...common}><rect x="3" y="3" width="18" height="18" rx="2" /><circle cx="8.5" cy="8.5" r="1.5" /><polyline points="21 15 16 10 5 21" /></svg>;
    case "save":return <svg {...common}><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" /><polyline points="17 21 17 13 7 13 7 21" /><polyline points="7 3 7 8 15 8" /></svg>;
    case "eye":return <svg {...common}><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" /><circle cx="12" cy="12" r="3" /></svg>;
    case "external":return <svg {...common}><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" /><polyline points="15 3 21 3 21 9" /><line x1="10" y1="14" x2="21" y2="3" /></svg>;
    case "zap":return <svg {...common}><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" /></svg>;
    case "info":return <svg {...common}><circle cx="12" cy="12" r="10" /><line x1="12" y1="16" x2="12" y2="12" /><line x1="12" y1="8" x2="12.01" y2="8" /></svg>;
    case "wrench":return <svg {...common}><path d="M14.7 6.3a4 4 0 0 0-5.4 5.4l-7 7 2 2 7-7a4 4 0 0 0 5.4-5.4l-2.6 2.6-2-2z" /></svg>;
    case "refresh":return <svg {...common}><polyline points="23 4 23 10 17 10" /><polyline points="1 20 1 14 7 14" /><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" /></svg>;
    case "more":return <svg {...common}><circle cx="12" cy="12" r="1" /><circle cx="19" cy="12" r="1" /><circle cx="5" cy="12" r="1" /></svg>;
    case "calendar":return <svg {...common}><rect x="3" y="4" width="18" height="18" rx="2" /><line x1="16" y1="2" x2="16" y2="6" /><line x1="8" y1="2" x2="8" y2="6" /><line x1="3" y1="10" x2="21" y2="10" /></svg>;
    case "globe":return <svg {...common}><circle cx="12" cy="12" r="10" /><line x1="2" y1="12" x2="22" y2="12" /><path d="M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20" /></svg>;
    case "dollar":return <svg {...common}><line x1="12" y1="1" x2="12" y2="23" /><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" /></svg>;
    case "facebook":return <svg {...common}><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" /></svg>;
    case "line":return <svg {...common}><rect x="3" y="4" width="18" height="14" rx="3" /><path d="M7 9v4M7 13l4-4M11 9v4M14 13V9M14 9c2 0 2 4 0 4M18 9v4" /></svg>;
    default:return <svg {...common}><circle cx="12" cy="12" r="3" /></svg>;
  }
};

/* ----- Product image: rich SVG photo when ProductPhoto available ----- */
const ProductImg = ({ product, size = "md" }) => {
  if (window.ProductPhoto) {
    return <window.ProductPhoto product={product} />;
  }
  const hue = HUE[(product.id - 1) % HUE.length];
  const bg = `hsl(${hue}, 30%, 95%)`;
  const stripe = `hsl(${hue}, 60%, 60%)`;
  const bgInline = {
    backgroundImage: `repeating-linear-gradient(135deg, transparent 0 14px, ${stripe}26 14px 16px), linear-gradient(180deg, ${bg}, #fff)`,
    backgroundColor: bg
  };
  return (
    <div className="ph" style={bgInline}>
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 6, color: `hsl(${hue}, 30%, 50%)` }}>
        <ToolGlyph cat={product.category} hue={hue} />
        <span style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, opacity: 0.7 }}>{product.sku}</span>
      </div>
    </div>);

};

/* simple stylized tool glyphs */
const ToolGlyph = ({ cat, hue }) => {
  const color = `hsl(${hue}, 50%, 40%)`;
  const acc = `hsl(${hue}, 70%, 55%)`;
  const common = { width: 64, height: 64, viewBox: "0 0 64 64", fill: "none", stroke: color, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (cat) {
    case "power":
      return (
        <svg {...common}>
          <rect x="14" y="22" width="28" height="14" rx="2" fill={acc + "40"} />
          <rect x="42" y="26" width="14" height="6" rx="1" fill={color} />
          <path d="M20 36v8h12v-8" />
          <circle cx="56" cy="29" r="2" fill={color} />
        </svg>);

    case "hand":
      return (
        <svg {...common}>
          <path d="M12 38l16-16 6 6-16 16-6-6z" fill={acc + "40"} />
          <rect x="36" y="14" width="14" height="14" rx="2" fill={color + "70"} />
          <path d="M12 38l-4 4 6 6 4-4" />
        </svg>);

    case "measure":
      return (
        <svg {...common}>
          <rect x="10" y="20" width="44" height="20" rx="3" fill={acc + "40"} />
          <path d="M14 24v4M22 24v6M30 24v4M38 24v6M46 24v4M50 24v6" />
        </svg>);

    case "fasten":
      return (
        <svg {...common}>
          <circle cx="22" cy="22" r="6" fill={acc + "40"} />
          <path d="M22 28v22M16 50h12" />
          <circle cx="44" cy="40" r="5" fill={color + "60"} />
          <path d="M44 45v9" />
        </svg>);

    case "safety":
      return (
        <svg {...common}>
          <path d="M16 36c0-10 7-18 16-18s16 8 16 18" fill={acc + "40"} />
          <path d="M14 36h36v4H14z" fill={color + "50"} />
          <path d="M30 22h4v8h-4z" />
        </svg>);

    case "storage":
      return (
        <svg {...common}>
          <rect x="10" y="20" width="44" height="28" rx="2" fill={acc + "30"} />
          <path d="M10 32h44M28 20v-4h8v4" />
          <circle cx="32" cy="40" r="2" fill={color} />
        </svg>);

    default:
      return null;
  }
};

/* ----- TOPBAR + NAV ----- */
function TopBar({ session, cart, route, navigate, openLogin, logout, query, setQuery }) {
  const cartCount = cart.reduce((s, i) => s + i.qty, 0);
  return (
    <div className="topbar">
      <div className="topbar-strip">
        <div className="wrap">
          <div className="flex gap-16 center">
            <a><Icon name="phone" size={12} /> 02-323-3710</a>
            <a><Icon name="mail" size={12} /> sales@intersupply1992.co.th</a>
            <a className="hide-sm"><Icon name="clock" size={12} /> จ-ส 8:00-17:30</a>
          </div>
          <div className="right">
            <a><Icon name="map-pin" size={12} /> ค้นหาสาขา</a>
            <a><Icon name="line" size={12} /> @intersupply1992</a>
            <a><Icon name="globe" size={12} /> TH / EN</a>
          </div>
        </div>
      </div>
      <div className="topbar-main">
        <div className="brand" onClick={() => navigate("home")}>
          <div className="brand-logo"><img src="assets/logo.png" alt="Inter Supply"/></div>
          <div className="brand-name">
            <div className="th">อินเตอร์ ซัพพลาย (1992)</div>
            <div className="en">INTER SUPPLY (1992) CO., LTD. </div>
          </div>
        </div>
        <div className="topbar-search">
          <input
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onFocus={() => navigate("catalog")}
            placeholder="ค้นหาสินค้า, SKU, รหัส / Search products, SKU..." />
          
          <Icon name="search" size={18} className="icon" />
        </div>
        <div className="topbar-actions">
          {session ?
          <button className="icon-btn" onClick={() => navigate(session.role === "admin" ? "admin" : session.role === "dealer" ? "dealer" : "catalog")}>
              <div className="avatar" style={{ background: "rgba(255,255,255,0.15)", color: "white" }}>{session.name.charAt(0)}</div>
              <span className="hide-sm">{session.name.split(" ")[0]}</span>
            </button> :

          <button className="icon-btn" onClick={openLogin}>
              <Icon name="user" size={18} />
              <span className="hide-sm">เข้าสู่ระบบ</span>
            </button>
          }
          <button className="icon-btn" onClick={() => navigate("cart")}>
            <Icon name="cart" size={18} />
            <span className="hide-sm">ใบเสนอราคา</span>
            {cartCount > 0 && <span className="badge">{cartCount}</span>}
          </button>
          {session &&
          <button className="icon-btn" title="ออกจากระบบ" onClick={logout}>
              <Icon name="log-out" size={16} />
            </button>
          }
        </div>
      </div>
      <nav className="nav">
        <div className="nav-wrap">
          <a className={route === "home" ? "active" : ""} onClick={() => navigate("home")}><Icon name="dashboard" size={14} /> หน้าหลัก</a>
          <a className={route === "catalog" ? "active" : ""} onClick={() => navigate("catalog")}><Icon name="grid" size={14} /> สินค้าทั้งหมด</a>
          <a onClick={() => navigate("catalog", { category: "power" })}>เครื่องมือไฟฟ้า</a>
          <a onClick={() => navigate("catalog", { category: "hand" })}>เครื่องมือช่าง</a>
          <a onClick={() => navigate("catalog", { category: "measure" })}>เครื่องมือวัด</a>
          <a onClick={() => navigate("catalog", { category: "safety" })}>เซฟตี้</a>
          <a onClick={() => navigate("catalog", { category: "storage" })}>กล่องเก็บ/ตู้</a>
          <a onClick={() => navigate("catalog", { sale: true })}>โปรโมชั่น <span className="pill">SALE</span></a>
          <div className="spacer"></div>
          {session?.role === "dealer" && <a className={route === "dealer" ? "active" : ""} onClick={() => navigate("dealer")}>Dealer Portal</a>}
          {session?.role === "admin" && <a className={route === "admin" ? "active" : ""} onClick={() => navigate("admin")}>Admin Panel</a>}
          <a className={route === "cart" ? "active" : ""} onClick={() => navigate("cart")}>ใบเสนอราคาของฉัน</a>
        </div>
      </nav>
    </div>);

}

/* ----- PRODUCT CARD ----- */
function ProductCard({ product: p, onAdd, onView, inCart, isDealer }) {
  const stockLabel = p.stock > 20 ? "พร้อมส่ง" : p.stock > 5 ? `เหลือ ${p.stock} ชิ้น` : p.stock > 0 ? `เหลือ ${p.stock} ชิ้น` : "หมดชั่วคราว";
  const stockClass = p.stock > 20 ? "" : p.stock > 0 ? "low" : "out";
  const [fav, setFav] = useState(false);
  return (
    <div className="product-card" onClick={() => onView(p)}>
      <div className="product-img">
        <ProductImg product={p} />
        {p.tag && <span className={`product-tag ${p.tag}`}>{p.tag === "new" ? "NEW" : p.tag === "sale" ? "SALE" : "HOT"}</span>}
        <button className={"product-fav" + (fav ? " on" : "")} onClick={(e) => {e.stopPropagation();setFav(!fav);}}>
          <Icon name="heart" size={15} />
        </button>
      </div>
      <div className="product-body">
        <div className="product-sku">{p.sku} · {p.brand}</div>
        <div className="product-name">{p.th}</div>
        <div className="product-desc">{p.desc}</div>
        <div className="product-meta">
          <div>
            <span className="product-price">฿{fmtMoney(isDealer ? p.dealerPrice : p.price)}<span className="unit">/ชิ้น</span></span>
            {p.oldPrice && <div className="product-price-old">฿{fmtMoney(p.oldPrice)}</div>}
          </div>
          <div className={`product-stock ${stockClass}`}>
            <Icon name={p.stock > 0 ? "check" : "x"} size={12} />
            {stockLabel}
          </div>
        </div>
      </div>
      {isDealer &&
      <div className="dealer-price-row">
          <span className="label"><Icon name="tag" size={11} /> Dealer Price</span>
          <span className="price">฿{fmtMoney(p.dealerPrice)} · -15%</span>
        </div>
      }
      <div className="product-actions">
        <button className="btn btn-outline btn-sm" onClick={(e) => {e.stopPropagation();onView(p);}}>
          <Icon name="eye" size={13} /> ดู
        </button>
        <button
          className={"btn btn-sm " + (inCart ? "btn-outline" : "btn-primary")}
          onClick={(e) => {e.stopPropagation();onAdd(p);}}
          disabled={p.stock === 0}>
          
          {inCart ? <><Icon name="check" size={13} /> เพิ่มแล้ว</> : <><Icon name="plus" size={13} /> ใบเสนอราคา</>}
        </button>
      </div>
    </div>);

}

/* ----- TOASTS ----- */
const ToastCtx = createContext();
function useToast() {return useContext(ToastCtx);}
function ToastProvider({ children }) {
  const [items, setItems] = useState([]);
  const push = useCallback((msg, type = "ok") => {
    const id = Math.random().toString(36).slice(2);
    setItems((it) => [...it, { id, msg, type }]);
    setTimeout(() => setItems((it) => it.filter((x) => x.id !== id)), 2800);
  }, []);
  return (
    <ToastCtx.Provider value={push}>
      {children}
      <div className="toasts">
        {items.map((t) =>
        <div key={t.id} className={"toast " + (t.type === "err" ? "err" : "")}>
            <Icon name={t.type === "err" ? "x" : "check"} size={16} className="ic" />
            <span>{t.msg}</span>
          </div>
        )}
      </div>
    </ToastCtx.Provider>);

}

/* ----- MODAL ----- */
function Modal({ open, onClose, title, children, footer, width }) {
  if (!open) return null;
  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal" style={{ maxWidth: width || 540 }} onClick={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <h3>{title}</h3>
          <button className="icon-btn" style={{ color: "var(--ink-500)" }} onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-foot">{footer}</div>}
      </div>
    </div>);

}

/* ----- QTY STEPPER ----- */
function QtyStepper({ value, onChange, min = 1, max = 999 }) {
  return (
    <div className="qty-stepper">
      <button onClick={() => onChange(Math.max(min, value - 1))}><Icon name="minus" size={14} /></button>
      <input value={value} onChange={(e) => {
        const v = parseInt(e.target.value || "0", 10);
        if (!Number.isNaN(v)) onChange(Math.max(min, Math.min(max, v)));
      }} />
      <button onClick={() => onChange(Math.min(max, value + 1))}><Icon name="plus" size={14} /></button>
    </div>);

}

Object.assign(window, { Icon, ProductImg, ToolGlyph, TopBar, ProductCard, ToastProvider, useToast, Modal, QtyStepper });