// NekoShop — shared UI primitives
// PixelCat, Nav, Footer, ProductCard, VideoPlayer, Placeholder, etc.

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

// ──────────────────────────────────────────────────────────────────
// PixelCat — the NoMen avatar, rendered in a circle.
// (Name kept for backwards compat with all existing callsites.)
// Accepts size; inkColor/accentColor are accepted but no longer used.
// ──────────────────────────────────────────────────────────────────
function PixelCat({ size = 28, inkColor, accentColor, className = "", style = {} }) {
  return (
    <span
      className={className}
      style={{
        display: "inline-block",
        width: size,
        height: size,
        borderRadius: "50%",
        overflow: "hidden",
        backgroundImage: "url(assets/logo.jpg)",
        backgroundSize: "cover",
        backgroundPosition: "center 22%",
        flexShrink: 0,
        boxShadow: "inset 0 0 0 1px oklch(0.92 0.005 60 / 0.4)",
        ...style,
      }}
      aria-label="NekoShop logo"
      role="img"
    />
  );
}

// ──────────────────────────────────────────────────────────────────
// Striped placeholder — for product thumbnails / hero media slots
// ──────────────────────────────────────────────────────────────────
function StripedPlaceholder({ hue = 22, label = "preview", aspect = "16/9", small = false, badge }) {
  const bg = `oklch(0.96 0.018 ${hue})`;
  const stripe = `oklch(0.88 0.05 ${hue})`;
  const ink = `oklch(0.32 0.06 ${hue})`;
  return (
    <div style={{
      position: "relative",
      width: "100%",
      aspectRatio: aspect,
      backgroundColor: bg,
      backgroundImage: `repeating-linear-gradient(135deg, ${stripe} 0 1px, transparent 1px 14px)`,
      borderRadius: 4,
      overflow: "hidden",
      display: "flex",
      alignItems: "flex-end",
      padding: small ? 10 : 16,
    }}>
      <div style={{
        fontFamily: "var(--mono)",
        fontSize: small ? 10 : 11,
        color: ink,
        letterSpacing: "0.04em",
        textTransform: "uppercase",
      }}>{label}</div>
      {badge && (
        <div style={{
          position: "absolute", top: small ? 8 : 12, left: small ? 8 : 12,
          fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.06em",
          textTransform: "uppercase", color: "var(--bg)", background: "var(--accent)",
          padding: "3px 7px", borderRadius: 2,
        }}>{badge}</div>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────
// VideoPlayer — real YouTube embed (click-to-load thumb → iframe)
// ──────────────────────────────────────────────────────────────────
function VideoPlayer({ videoId, imageSrc, hue = 22, label = "Trailer", note }) {
  const [loaded, setLoaded] = useState(false);
  if (!videoId) {
    // Static image preview (e.g. products without a video trailer)
    if (imageSrc) {
      return (
        <div style={{ position: "relative", width: "100%", aspectRatio: "16/9", borderRadius: 4, overflow: "hidden", background: "var(--ink)" }}>
          <img src={imageSrc} alt={label} style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
        </div>
      );
    }
    return (
      <div style={{ position: "relative", width: "100%", aspectRatio: "16/9", borderRadius: 4, overflow: "hidden" }}>
        <StripedPlaceholder hue={hue} label={note || "no preview available"} />
      </div>
    );
  }
  if (loaded) {
    return (
      <div style={{ position: "relative", width: "100%", aspectRatio: "16/9", borderRadius: 4, overflow: "hidden", background: "black" }}>
        <iframe
          src={`https://www.youtube.com/embed/${videoId}?autoplay=1&rel=0`}
          title={label}
          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
          allowFullScreen
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", border: 0 }}
        />
      </div>
    );
  }
  return (
    <div onClick={() => setLoaded(true)} style={{
      position: "relative", width: "100%", aspectRatio: "16/9", borderRadius: 4,
      overflow: "hidden", cursor: "pointer", background: "black",
    }}>
      <img
        src={`https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`}
        alt={label}
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }}
        onError={(e) => { e.currentTarget.style.display = "none"; }}
      />
      <div style={{ position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.45), rgba(0,0,0,0.05))" }} />
      <div style={{
        position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center",
      }}>
        <div style={{
          width: 72, height: 72, borderRadius: "50%", background: "var(--accent)",
          display: "flex", alignItems: "center", justifyContent: "center",
          boxShadow: "0 12px 36px rgba(0,0,0,0.35)",
        }}>
          <svg width="24" height="24" viewBox="0 0 24 24"><polygon points="7,4 7,20 21,12" fill="white" /></svg>
        </div>
      </div>
      <div style={{
        position: "absolute", left: 14, bottom: 12, color: "white",
        fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.06em", textTransform: "uppercase",
        textShadow: "0 1px 4px rgba(0,0,0,0.6)",
      }}>
        ▶ Play preview · YouTube
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────
// Currency context
// ──────────────────────────────────────────────────────────────────
const CurrencyCtx = createContext({ currency: "IDR", setCurrency: () => {} });
function CurrencyProvider({ children }) {
  const valid = ["IDR", "USD", "Robux"];
  const [currency, setCurrency] = useState(() => {
    const s = localStorage.getItem("neko.currency");
    return valid.includes(s) ? s : "IDR";
  });
  useEffect(() => { localStorage.setItem("neko.currency", currency); }, [currency]);
  return <CurrencyCtx.Provider value={{ currency, setCurrency }}>{children}</CurrencyCtx.Provider>;
}
function useCurrency() { return useContext(CurrencyCtx); }
function priceKey(currency) {
  if (currency === "USD") return "usd";
  if (currency === "Robux") return "robux";
  return "idr";
}
function formatPrice(price, currency) {
  if (currency === "USD") return `$${price.usd}`;
  if (currency === "Robux") {
    return `R$ ${Number(price.robux).toLocaleString("en-US")}`;
  }
  // IDR: 1.100.000 style (dots)
  const s = String(price.idr).replace(/\B(?=(\d{3})+(?!\d))/g, ".");
  return `Rp ${s}`;
}
function priceFromTotal(total, currency) {
  // For totals — build a price-shaped object so formatPrice works.
  return { idr: total, usd: total, robux: total };
}

// ──────────────────────────────────────────────────────────────────
// Event pricing — auto-switches IDR/USD to the discounted eventPrice
// while window.NEKO_EVENT is active. Robux is always full price.
// ──────────────────────────────────────────────────────────────────
function isEventActive() {
  const e = window.NEKO_EVENT;
  if (!e) return false;
  const now = Date.now();
  return now >= new Date(e.start).getTime() && now <= new Date(e.end).getTime();
}
// Returns the price shape to actually CHARGE, plus the original for compare display.
function effectivePrice(product, currency) {
  const orig = product.price;
  if (currency === "Robux") return { price: orig, original: null, isEvent: false };
  if (!isEventActive() || !product.eventPrice) return { price: orig, original: null, isEvent: false };
  // Build a synthesised price object with discounted IDR/USD but original Robux
  const ev = {
    idr: product.eventPrice.idr,
    usd: product.eventPrice.usd,
    robux: orig.robux,
  };
  return { price: ev, original: orig, isEvent: true };
}
// Inline price display that shows event price + struck-through original when applicable.
function PriceLabel({ product, currency, size = "md", color }) {
  const { price, original, isEvent } = effectivePrice(product, currency);
  const fontSize = size === "lg" ? 30 : size === "sm" ? 13 : 14;
  const stroke   = size === "lg" ? 16 : size === "sm" ? 11 : 12;
  const mainColor = isEvent ? "var(--accent)" : (color || "var(--ink)");
  const origColor = color ? "rgba(255,255,255,0.55)" : "var(--muted)";
  return (
    <span style={{ display: "inline-flex", alignItems: "baseline", gap: 8, fontFamily: "var(--mono)" }}>
      <span style={{ fontSize, fontWeight: 600, color: mainColor }}>
        {formatPrice(price, currency)}
      </span>
      {isEvent && (
        <span style={{ fontSize: stroke, color: origColor, textDecoration: "line-through" }}>
          {formatPrice(original, currency)}
        </span>
      )}
    </span>
  );
}

// ──────────────────────────────────────────────────────────────────
// Cart context — line items with qty, persisted
// ──────────────────────────────────────────────────────────────────
const CartCtx = createContext(null);
function CartProvider({ children }) {
  const [items, setItems] = useState(() => {
    try { return JSON.parse(localStorage.getItem("neko.cart") || "[]"); } catch { return []; }
  });
  useEffect(() => { localStorage.setItem("neko.cart", JSON.stringify(items)); }, [items]);
  const add = useCallback((id, qty = 1) => {
    setItems((it) => {
      const found = it.find(x => x.id === id);
      if (found) return it.map(x => x.id === id ? { ...x, qty: x.qty + qty } : x);
      return [...it, { id, qty }];
    });
  }, []);
  const setQty = useCallback((id, qty) => {
    setItems((it) => qty <= 0 ? it.filter(x => x.id !== id) : it.map(x => x.id === id ? { ...x, qty } : x));
  }, []);
  const remove = useCallback((id) => setItems(it => it.filter(x => x.id !== id)), []);
  const clear = useCallback(() => setItems([]), []);
  const count = items.reduce((a, x) => a + x.qty, 0);
  return <CartCtx.Provider value={{ items, add, setQty, remove, clear, count }}>{children}</CartCtx.Provider>;
}
function useCart() { return useContext(CartCtx); }

// ──────────────────────────────────────────────────────────────────
// Router — hash-based
// ──────────────────────────────────────────────────────────────────
const RouterCtx = createContext({ route: { name: "home" }, go: () => {} });
function parseHash() {
  const h = (location.hash || "#/").slice(1);
  const parts = h.split("/").filter(Boolean);
  if (parts.length === 0) return { name: "home" };
  if (parts[0] === "c" && parts[1]) return { name: "category", id: parts[1] };
  if (parts[0] === "p" && parts[1]) return { name: "product", id: parts[1] };
  if (parts[0] === "cart") return { name: "cart" };
  if (parts[0] === "checkout") return { name: "checkout" };
  if (parts[0] === "success") return { name: "success", id: parts[1] };
  if (parts[0] === "browse") return { name: "browse" };
  if (parts[0] === "info") return { name: "info", section: parts[1] };
  return { name: "home" };
}
function RouterProvider({ children }) {
  const [route, setRoute] = useState(parseHash());
  useEffect(() => {
    const onHash = () => { setRoute(parseHash()); window.scrollTo({ top: 0, behavior: "instant" }); };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  const go = useCallback((path) => { location.hash = path; }, []);
  return <RouterCtx.Provider value={{ route, go }}>{children}</RouterCtx.Provider>;
}
function useRouter() { return useContext(RouterCtx); }

// ──────────────────────────────────────────────────────────────────
// EventBanner — only renders when window.NEKO_EVENT window is active.
// ──────────────────────────────────────────────────────────────────
function EventBanner() {
  const { go } = useRouter();
  const e = window.NEKO_EVENT;
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    if (!e) return;
    const i = setInterval(() => setNow(Date.now()), 60000); // tick every minute
    return () => clearInterval(i);
  }, []);
  if (!e) return null;
  const start = new Date(e.start).getTime();
  const end   = new Date(e.end).getTime();
  if (now < start || now > end) return null;

  // Countdown to end (days / hours)
  const ms = end - now;
  const days = Math.floor(ms / (24 * 3600 * 1000));
  const hrs  = Math.floor((ms % (24 * 3600 * 1000)) / (3600 * 1000));
  const countdown = days > 0 ? `${days}d ${hrs}h left` : `${hrs}h left`;

  return (
    <div onClick={() => go("/browse")} style={{
      background: "var(--ink)", color: "var(--bg)",
      padding: "10px 20px", cursor: "pointer",
      display: "flex", alignItems: "center", justifyContent: "center", gap: 16,
      fontFamily: "var(--sans)", fontSize: 13, fontWeight: 500,
      borderBottom: "1px solid var(--ink)",
    }}>
      <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
        <FireIcon /> <strong>{e.name}</strong>
      </span>
      <span style={{ color: "oklch(0.78 0.005 60)" }}>·</span>
      <span style={{ color: "oklch(0.85 0.005 60)" }}>{e.tagline} — discounts on IDR &amp; USD payments</span>
      <span style={{ color: "oklch(0.78 0.005 60)" }}>·</span>
      <span style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.04em", textTransform: "uppercase", color: "var(--accent)" }}>{countdown}</span>
      <span style={{ marginLeft: 6, padding: "3px 10px", borderRadius: 999, background: "var(--accent)", color: "white", fontSize: 11, fontWeight: 600 }}>
        Browse deals →
      </span>
    </div>
  );
}
function FireIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="var(--accent)">
      <path d="M12 2c0 4 5 4 5 9a5 5 0 1 1-10 0c0-2 1-3 2-4 0 2 1 3 2 3 0-3-2-4 1-8z" />
    </svg>
  );
}

// ──────────────────────────────────────────────────────────────────
// Nav (top) — logo, links, currency switcher, cart
// ──────────────────────────────────────────────────────────────────
function TopNav() {
  const { go, route } = useRouter();
  const { currency, setCurrency } = useCurrency();
  const { count } = useCart();
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <header style={{
      position: "sticky", top: 0, zIndex: 50, background: "var(--bg)",
      borderBottom: `1px solid ${scrolled ? "var(--border)" : "transparent"}`,
      transition: "border-color 200ms ease",
    }}>
      <div className="container" style={{ display: "flex", alignItems: "center", height: 64, gap: 32 }}>
        <a href="#/" onClick={(e)=>{e.preventDefault();go("/");}} style={{ display: "flex", alignItems: "center", gap: 10, textDecoration: "none", color: "var(--ink)" }}>
          <PixelCat size={28} accentColor="var(--accent)" />
          <span style={{ fontWeight: 700, fontSize: 17, letterSpacing: "-0.01em" }}>NekoShop</span>
        </a>
        <nav style={{ display: "flex", alignItems: "center", gap: 28, marginLeft: 16 }}>
          <NavLink active={route.name === "browse" || route.name === "home"} onClick={() => go("/browse")}>Browse</NavLink>
          <NavLink active={route.name === "category" && route.id === "bundle"} onClick={() => go("/c/bundle")}>Bundles</NavLink>
          <NavLink active={route.name === "category" && route.id === "donation"} onClick={() => go("/c/donation")}>Donations</NavLink>
          <NavLink active={route.name === "category" && route.id === "music"} onClick={() => go("/c/music")}>DJ &amp; Music</NavLink>
        </nav>
        <div style={{ flex: 1 }} />
        <CurrencySwitch currency={currency} setCurrency={setCurrency} />
        <button onClick={() => go("/cart")} style={{
          display: "flex", alignItems: "center", gap: 8, padding: "7px 14px",
          border: "1px solid var(--border)", background: "var(--bg)", borderRadius: 999,
          fontFamily: "var(--sans)", fontSize: 13, fontWeight: 500, cursor: "pointer", color: "var(--ink)",
        }}>
          <CartIcon />
          <span>Cart</span>
          {count > 0 && (
            <span style={{
              fontFamily: "var(--mono)", fontSize: 11, background: "var(--accent)", color: "var(--bg)",
              padding: "1px 7px", borderRadius: 10, minWidth: 20, textAlign: "center",
            }}>{count}</span>
          )}
        </button>
      </div>
    </header>
  );
}
function NavLink({ active, onClick, children }) {
  return (
    <button onClick={onClick} style={{
      background: "transparent", border: "none", padding: 0, cursor: "pointer",
      fontFamily: "var(--sans)", fontSize: 14, fontWeight: 500,
      color: active ? "var(--ink)" : "var(--muted)",
      position: "relative",
    }}>
      {children}
      {active && <span style={{ position: "absolute", left: 0, right: 0, bottom: -22, height: 2, background: "var(--accent)" }} />}
    </button>
  );
}
function CurrencySwitch({ currency, setCurrency }) {
  return (
    <div style={{
      display: "inline-flex", border: "1px solid var(--border)", borderRadius: 999, padding: 2,
      fontFamily: "var(--mono)", fontSize: 11,
    }}>
      {["IDR", "USD", "Robux"].map(c => (
        <button key={c} onClick={() => setCurrency(c)} style={{
          padding: "5px 11px", borderRadius: 999, border: "none", cursor: "pointer",
          background: currency === c ? "var(--ink)" : "transparent",
          color: currency === c ? "var(--bg)" : "var(--muted)",
          letterSpacing: "0.04em", fontWeight: 600,
        }}>{c === "Robux" ? "R$" : c}</button>
      ))}
    </div>
  );
}
function CartIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4">
      <path d="M2 3h2l1.5 8.5h7.5L14.5 6H5"/>
      <circle cx="6.5" cy="13.5" r="1"/>
      <circle cx="12" cy="13.5" r="1"/>
    </svg>
  );
}

// NekoShop — Footer
function FooterCol({ title, children }) {
  return (
    <div>
      <div style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 14 }}>{title}</div>
      <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 9 }}>
        {children}
      </ul>
    </div>
  );
}
function FooterLink({ href, onClick, external, children }) {
  const props = external
    ? { href, target: "_blank", rel: "noreferrer" }
    : { href, onClick: (e) => { if (onClick) { e.preventDefault(); onClick(); } } };
  return <li><a {...props} style={{ color: "var(--ink)", fontSize: 13, textDecoration: "none" }}>{children}</a></li>;
}

function Footer() {
  const cfg = window.NEKO_CONFIG;
  const { go } = useRouter();
  const s = cfg.socials || {};
  return (
    <footer style={{ borderTop: "1px solid var(--border)", marginTop: 96, paddingTop: 48, paddingBottom: 56 }}>
      <div className="container" style={{ display: "grid", gridTemplateColumns: "2fr 1fr 1fr 1fr 1.1fr", gap: 40 }}>
        <div>
          <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 16 }}>
            <PixelCat size={26} accentColor="var(--accent)" />
            <span style={{ fontWeight: 700, fontSize: 16 }}>NekoShop</span>
          </div>
          <div style={{ color: "var(--muted)", fontSize: 13, lineHeight: 1.6, maxWidth: 320 }}>
            Roblox systems crafted in Indonesia. Donation, VIP, club kits, camera tools — drop them into your game and ship.
          </div>
          <div style={{ marginTop: 18, display: "flex", gap: 8, flexWrap: "wrap" }}>
            {s.youtubeMain && <SocialPill href={s.youtubeMain.url} label="YouTube" icon={<YtIcon />} />}
            {s.tiktokMain  && <SocialPill href={s.tiktokMain.url}  label="TikTok"  icon={<TtIcon />} />}
            {s.discordHandle && <SocialPill href={cfg.discordInvite} label="Discord" icon={<DcIcon />} />}
          </div>
        </div>
        <FooterCol title="Shop">
          <FooterLink href="#/c/donation" onClick={() => go("/c/donation")}>Donation Systems</FooterLink>
          <FooterLink href="#/c/vip"      onClick={() => go("/c/vip")}>VIP Systems</FooterLink>
          <FooterLink href="#/c/bundle"   onClick={() => go("/c/bundle")}>Bundled Packages</FooterLink>
          <FooterLink href="#/c/music"    onClick={() => go("/c/music")}>DJ &amp; Music</FooterLink>
          <FooterLink href="#/c/camera"   onClick={() => go("/c/camera")}>Camera &amp; Studio</FooterLink>
        </FooterCol>
        <FooterCol title="Support">
          <FooterLink href="#/info/install" onClick={() => go("/info/install")}>Install guide</FooterLink>
          <FooterLink href="#/info/license" onClick={() => go("/info/license")}>License terms</FooterLink>
          <FooterLink href="#/info/refund"  onClick={() => go("/info/refund")}>Refund policy</FooterLink>
          <FooterLink href={cfg.discordInvite} external>Discord community ↗</FooterLink>
        </FooterCol>
        <FooterCol title="Pay with">
          <FooterLink href="#/info/install" onClick={() => go("/info/install")}>QRIS (all e-wallets)</FooterLink>
          <FooterLink href="#/info/install" onClick={() => go("/info/install")}>PayPal (international)</FooterLink>
          <FooterLink href={cfg.robloxStoreUrl} external>Robux gamepass ↗</FooterLink>
        </FooterCol>
        <FooterCol title="Follow">
          {s.youtubeMain && <FooterLink href={s.youtubeMain.url} external>{s.youtubeMain.label} ↗</FooterLink>}
          {s.youtubeAlt  && <FooterLink href={s.youtubeAlt.url}  external>{s.youtubeAlt.label} ↗</FooterLink>}
          {s.tiktokMain  && <FooterLink href={s.tiktokMain.url}  external>{s.tiktokMain.label} ↗</FooterLink>}
          {s.tiktokAlt   && <FooterLink href={s.tiktokAlt.url}   external>{s.tiktokAlt.label} ↗</FooterLink>}
          {s.discordHandle && (
            <li><span style={{ color: "var(--ink)", fontSize: 13 }}>{s.discordHandle.label}</span></li>
          )}
        </FooterCol>
      </div>
      <div className="container" style={{ marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--border)", display: "flex", justifyContent: "space-between", color: "var(--muted)", fontSize: 12, fontFamily: "var(--mono)" }}>
        <span>© 2026 NEKOSHOP — JAKARTA, ID</span>
        <span>BUILT WITH PIXELS &amp; WHITESPACE</span>
      </div>
    </footer>
  );
}

function SocialPill({ href, label, icon }) {
  return (
    <a href={href} target="_blank" rel="noreferrer" style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      padding: "6px 12px", borderRadius: 999,
      border: "1px solid var(--border)", background: "var(--bg)",
      textDecoration: "none", color: "var(--ink)",
      fontSize: 12, fontWeight: 500, fontFamily: "var(--sans)",
    }}>
      {icon} {label}
    </a>
  );
}
function YtIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
      <rect x="2" y="6" width="20" height="12" rx="3" fill="var(--accent)" />
      <polygon points="10,9 10,15 16,12" fill="white" />
    </svg>
  );
}
function TtIcon() {
  return (
    <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
      <path d="M14 3v11.5a3 3 0 1 1-3-3" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
      <path d="M14 3a6 6 0 0 0 6 5" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}
function DcIcon() {
  return (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="var(--ink)">
      <path d="M13.5 3.5A12 12 0 0 0 10.4 2.6l-.2.4a10.6 10.6 0 0 0-4.4 0l-.2-.4A12 12 0 0 0 2.5 3.5C1 6 .5 8.5 1 11c1.4 1 2.7 1.6 4 2l.6-.9a8 8 0 0 1-1.4-.7l.3-.2a8.4 8.4 0 0 0 7 0l.3.2a8 8 0 0 1-1.4.7l.6.9c1.3-.4 2.6-1 4-2 .6-3-.2-5.4-1.5-7.5zM6 9.5c-.6 0-1.2-.6-1.2-1.4S5.4 6.7 6 6.7c.7 0 1.2.6 1.2 1.4S6.7 9.5 6 9.5zm4 0c-.6 0-1.2-.6-1.2-1.4s.6-1.4 1.2-1.4 1.2.6 1.2 1.4-.5 1.4-1.2 1.4z"/>
    </svg>
  );
}

// ──────────────────────────────────────────────────────────────────
// ProductCard — used in grids
// ──────────────────────────────────────────────────────────────────
function ProductCard({ product, onClick }) {
  const { currency } = useCurrency();
  const cat = window.NEKO_DATA.cats[product.cat];
  const hue = window.NEKO_DATA.hue[product.cat];
  const ytId = product.video && product.video.kind === "youtube" ? product.video.id : null;
  const imgSrc = product.image || null;
  const { isEvent } = effectivePrice(product, currency);
  const cardBadge = isEvent ? "SALE" : product.badge;
  const hi = product.highlight;
  return (
    <article onClick={onClick} style={{
      cursor: "pointer", display: "flex", flexDirection: "column",
      border: hi ? "1.5px solid var(--accent)" : "1px solid var(--border)", borderRadius: 6, overflow: "hidden",
      background: "var(--bg)",
      boxShadow: hi ? "0 0 0 4px oklch(0.62 0.20 22 / 0.12), 0 8px 28px oklch(0.62 0.20 22 / 0.16)" : "none",
      transition: "border-color 160ms ease, transform 160ms ease, box-shadow 160ms ease",
    }}
    onMouseEnter={(e)=>{e.currentTarget.style.borderColor="var(--ink)";}}
    onMouseLeave={(e)=>{e.currentTarget.style.borderColor=hi?"var(--accent)":"var(--border)";}}>
      {ytId ? (
        <div style={{ position: "relative", width: "100%", aspectRatio: "16/9", background: "var(--ink)", overflow: "hidden" }}>
          <img src={`https://i.ytimg.com/vi/${ytId}/hqdefault.jpg`} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
          <div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", background: "rgba(0,0,0,0.18)" }}>
            <div style={{ width: 42, height: 42, borderRadius: "50%", background: "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "0 6px 20px rgba(0,0,0,0.3)" }}>
              <svg width="14" height="14" viewBox="0 0 22 22"><polygon points="6,3 6,19 19,11" fill="var(--accent)" /></svg>
            </div>
          </div>
          {cardBadge && (
            <div style={{
              position: "absolute", top: 10, left: 10,
              fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.06em",
              textTransform: "uppercase", color: "white", background: "var(--accent)",
              padding: "3px 7px", borderRadius: 2,
            }}>{cardBadge}</div>
          )}
        </div>
      ) : imgSrc ? (
        <div style={{ position: "relative", width: "100%", aspectRatio: "16/9", background: "var(--ink)", overflow: "hidden" }}>
          <img src={imgSrc} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
          {cardBadge && (
            <div style={{
              position: "absolute", top: 10, left: 10,
              fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.06em",
              textTransform: "uppercase", color: "white", background: "var(--accent)",
              padding: "3px 7px", borderRadius: 2,
            }}>{cardBadge}</div>
          )}
        </div>
      ) : (
        <StripedPlaceholder hue={hue} label={`${product.id}.mp4`} badge={cardBadge} />
      )}
      <div style={{ padding: "14px 14px 16px" }}>
        <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 6 }}>
          {cat.label}
        </div>
        <h3 style={{ fontSize: 15, fontWeight: 600, margin: 0, lineHeight: 1.3, letterSpacing: "-0.005em" }}>
          {product.name}
        </h3>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 14 }}>
          <PriceLabel product={product} currency={currency} size="sm" />
          <div style={{ display: "flex", alignItems: "center", gap: 4, color: "var(--muted)", fontSize: 12, fontFamily: "var(--mono)" }}>
            <Star /> {product.rating.toFixed(1)}
          </div>
        </div>
      </div>
    </article>
  );
}
function Star() {
  return <svg width="11" height="11" viewBox="0 0 11 11"><polygon points="5.5,1 6.85,4.05 10,4.4 7.65,6.55 8.35,9.7 5.5,8.1 2.65,9.7 3.35,6.55 1,4.4 4.15,4.05" fill="var(--accent)"/></svg>;
}

// ──────────────────────────────────────────────────────────────────
// Buttons
// ──────────────────────────────────────────────────────────────────
function Btn({ children, primary, onClick, full, type, disabled, style={} }) {
  const base = {
    fontFamily: "var(--sans)", fontWeight: 500, fontSize: 14,
    padding: "12px 22px", borderRadius: 999, cursor: disabled ? "not-allowed" : "pointer",
    transition: "background 140ms ease, color 140ms ease, opacity 140ms",
    width: full ? "100%" : "auto",
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
    opacity: disabled ? 0.5 : 1,
    border: "1px solid",
  };
  const variant = primary
    ? { background: "var(--ink)", color: "var(--bg)", borderColor: "var(--ink)" }
    : { background: "var(--bg)", color: "var(--ink)", borderColor: "var(--border)" };
  return (
    <button onClick={onClick} type={type} disabled={disabled} style={{ ...base, ...variant, ...style }}>
      {children}
    </button>
  );
}

// Expose to other Babel scripts
Object.assign(window, {
  PixelCat, StripedPlaceholder, VideoPlayer,
  CurrencyProvider, useCurrency, formatPrice, priceKey, priceFromTotal,
  isEventActive, effectivePrice, PriceLabel,
  CartProvider, useCart,
  RouterProvider, useRouter,
  TopNav, Footer, ProductCard, Btn, Star,
  EventBanner,
});
