// cart.jsx — DropX cart system: CartProvider, useCart, CartDrawer, DropCatalog
// Versão integrada com a API: carrega produtos do backend, mas mantém
// o carrinho local até o checkout (mais leve, sem precisar de auth pra navegar).

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

// ── Configuração de estoque ───────────────────────────────────────────────
const LOW_STOCK_THRESHOLD = 3;
const STOCK_OVERRIDES_KEY = "dropx_stock_overrides";
const STOCK_EVENT = "dropx-stock-changed";

function readStockOverrides() {
  try { return JSON.parse(localStorage.getItem(STOCK_OVERRIDES_KEY) || "{}"); } catch { return {}; }
}
function stockKey(productId, colorId, size) {
  return `${productId}::${colorId || "_"}::${size || "_"}`;
}
function writeStockOverride(productId, colorId, size, value) {
  const o = readStockOverrides();
  const k = stockKey(productId, colorId, size);
  if (value == null || value === "") delete o[k];
  else o[k] = Math.max(0, Math.floor(Number(value) || 0));
  try { localStorage.setItem(STOCK_OVERRIDES_KEY, JSON.stringify(o)); } catch {}
  window.dispatchEvent(new Event(STOCK_EVENT));
}
// Estoque disponível pra (produto, cor, tamanho). Sob encomenda = Infinity.
function getStock(product, colorId, size) {
  if (product.fulfillment === "on_demand") return Infinity;
  const overrides = readStockOverrides();
  const k = stockKey(product.id, colorId, size);
  if (overrides[k] != null) return overrides[k];
  const matrix = product.stock || {};
  if (colorId && matrix[colorId]) {
    return size && matrix[colorId][size] != null ? matrix[colorId][size] : 0;
  }
  if (size && matrix[size] != null) return matrix[size];
  // Sem matriz definida: cai pro stock da variant (se existir) ou trata como ilimitado
  if (size) {
    const v = (product.variants || []).find(x => x.size === size);
    if (v && v.stock != null) return v.stock;
  }
  return Infinity;
}
// Soma do estoque de uma cor (em todos tamanhos) — usado pro "esgotado" da cor toda
function colorTotalStock(product, colorId) {
  if (product.fulfillment === "on_demand") return Infinity;
  const sizes = (product.variants || []).map(v => v.size);
  let total = 0;
  for (const s of sizes) {
    const n = getStock(product, colorId, s);
    if (n === Infinity) return Infinity;
    total += n;
  }
  return total;
}

// ── Fallback estático (se a API estiver offline) ─────────────────────────────
// Cada produto pode ter um array `colors` (id, name, hex, image_url).
// Trocar a cor troca a foto exibida. Se o produto não tiver `colors`, o card
// se comporta como antes (foto única).
const STATIC_FALLBACK = [
  { id: "hoodie-boxy",    slug: "hoodie-boxy",    tag: "MOLETOM",     category: "Moletom",   name: "Hoodie Boxy",  price_cents: 28000,
    fulfillment: "ready",
    colors: [
      { id: "preto",   name: "Preto",   hex: "#15100b", image_url: null },
      { id: "creme",   name: "Creme",   hex: "#e9e3d2", image_url: null },
      { id: "musgo",   name: "Musgo",   hex: "#4a5236", image_url: null }
    ],
    stock: {
      preto: { P: 4, M: 8, G: 6, GG: 2 },
      creme: { P: 2, M: 5, G: 0, GG: 3 },
      musgo: { P: 1, M: 3, G: 4, GG: 0 }
    },
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "sneaker-low",    slug: "sneaker-low",    tag: "TÊNIS",       category: "Tênis",     name: "Sneaker Low",  price_cents: 42000,
    fulfillment: "on_demand",
    colors: [
      { id: "branco",  name: "Branco",  hex: "#efeae0", image_url: null },
      { id: "preto",   name: "Preto",   hex: "#1a1410", image_url: null },
      { id: "areia",   name: "Areia",   hex: "#c4a578", image_url: null }
    ],
    variants: ["39","40","41","42","43","44"].map(s => ({ size: s })) },
  { id: "puffer-tech",    slug: "puffer-tech",    tag: "JAQUETA",     category: "Jaqueta",   name: "Puffer Tech",  price_cents: 58000,
    fulfillment: "ready",
    colors: [
      { id: "preto",   name: "Preto",   hex: "#15100b", image_url: null },
      { id: "grafite", name: "Grafite", hex: "#3a3833", image_url: null }
    ],
    stock: {
      preto:   { P: 2, M: 3, G: 1, GG: 0 },
      grafite: { P: 0, M: 0, G: 0, GG: 0 }
    },
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "crossbody",      slug: "crossbody",      tag: "BOLSA",       category: "Bolsa",     name: "Crossbody",    price_cents: 22000,
    fulfillment: "ready",
    colors: [
      { id: "preto",   name: "Preto",   hex: "#15100b", image_url: null },
      { id: "caramelo",name: "Caramelo",hex: "#9a5c2e", image_url: null }
    ],
    stock: {
      preto:    { UN: 7 },
      caramelo: { UN: 2 }
    },
    variants: [{ size: "UN" }] },
  { id: "baggy-jean",     slug: "baggy-jean",     tag: "CALÇA",       category: "Calça",     name: "Baggy Jean",   price_cents: 32000,
    fulfillment: "on_demand",
    colors: [
      { id: "indigo",  name: "Indigo",  hex: "#2a3a5c", image_url: null },
      { id: "lavado",  name: "Lavado",  hex: "#7a8aa3", image_url: null },
      { id: "preto",   name: "Preto",   hex: "#1a1410", image_url: null }
    ],
    variants: ["38","40","42","44","46"].map(s => ({ size: s })) },
  { id: "runner-v2",      slug: "runner-v2",      tag: "TÊNIS",       category: "Tênis",     name: "Runner V2",    price_cents: 46000,
    fulfillment: "ready",
    colors: [
      { id: "ouro",    name: "Ouro",    hex: "#e0a040", image_url: null },
      { id: "branco",  name: "Branco",  hex: "#efeae0", image_url: null },
      { id: "marinho", name: "Marinho", hex: "#1d2a44", image_url: null }
    ],
    stock: {
      ouro:    { 39: 1, 40: 2, 41: 0, 42: 3, 43: 0, 44: 1 },
      branco:  { 39: 0, 40: 1, 41: 4, 42: 5, 43: 2, 44: 0 },
      marinho: { 39: 0, 40: 0, 41: 0, 42: 0, 43: 0, 44: 0 }
    },
    variants: ["39","40","41","42","43","44"].map(s => ({ size: s })) },
  { id: "tee-heavy",      slug: "tee-heavy",      tag: "CAMISETA",    category: "Camiseta",  name: "Tee Heavy",    price_cents: 20000,
    fulfillment: "ready",
    colors: [
      { id: "preto",   name: "Preto",   hex: "#15100b", image_url: null },
      { id: "branco",  name: "Branco",  hex: "#efeae0", image_url: null },
      { id: "areia",   name: "Areia",   hex: "#c9b896", image_url: null },
      { id: "vinho",   name: "Vinho",   hex: "#5c1a1a", image_url: null }
    ],
    stock: {
      preto:  { P: 12, M: 18, G: 14, GG: 6 },
      branco: { P: 10, M: 15, G: 12, GG: 4 },
      areia:  { P: 3, M: 5, G: 2, GG: 1 },
      vinho:  { P: 0, M: 1, G: 0, GG: 0 }
    },
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "trench-mid",     slug: "trench-mid",     tag: "CASACO",      category: "Casaco",    name: "Trench Mid",   price_cents: 64000,
    fulfillment: "on_demand",
    colors: [
      { id: "camel",   name: "Camel",   hex: "#a87a45", image_url: null },
      { id: "preto",   name: "Preto",   hex: "#15100b", image_url: null }
    ],
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "shorts-cargo",  slug: "shorts-cargo",   tag: "SHORTS",      category: "Shorts",    name: "Shorts Cargo", price_cents: 18000,
    fulfillment: "ready",
    colors: [
      { id: "bege",   name: "Bege",   hex: "#c9b896", image_url: null },
      { id: "preto",  name: "Preto",  hex: "#15100b", image_url: null },
      { id: "musgo",  name: "Musgo",  hex: "#4a5236", image_url: null }
    ],
    stock: {
      bege:  { P: 6, M: 9, G: 4, GG: 2 },
      preto: { P: 3, M: 7, G: 5, GG: 0 },
      musgo: { P: 1, M: 2, G: 0, GG: 0 }
    },
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "shorts-malha",  slug: "shorts-malha",   tag: "SHORTS",      category: "Shorts",    name: "Shorts Malha", price_cents: 14000,
    fulfillment: "ready",
    colors: [
      { id: "preto",  name: "Preto",  hex: "#15100b", image_url: null },
      { id: "cinza",  name: "Cinza",  hex: "#6a6a6a", image_url: null }
    ],
    stock: {
      preto: { P: 8, M: 12, G: 9, GG: 3 },
      cinza: { P: 2, M: 4, G: 1, GG: 0 }
    },
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] },
  { id: "crew-felpa",    slug: "crew-felpa",     tag: "MOLETOM",     category: "Moletom",   name: "Crew Felpa",   price_cents: 26000,
    fulfillment: "on_demand",
    colors: [
      { id: "creme",  name: "Creme",  hex: "#e9e3d2", image_url: null },
      { id: "preto",  name: "Preto",  hex: "#15100b", image_url: null },
      { id: "bordô",  name: "Bordô",  hex: "#5c1a1a", image_url: null }
    ],
    variants: [{ size: "P" }, { size: "M" }, { size: "G" }, { size: "GG" }] }
];

// ── CONTEXT ──────────────────────────────────────────────────────────────────
const CartCtx = createContext(null);
const useCart = () => useContext(CartCtx);

function CartProvider({ children }) {
  const [items, setItems] = useState(() => {
    try { return JSON.parse(localStorage.getItem("dropx_cart") || "[]"); } catch { return []; }
  });
  const [products, setProducts] = useState([]);
  const [productsLoading, setProductsLoading] = useState(true);
  const [productsError, setProductsError] = useState(null);
  const [catalogOpen, setCatalogOpen] = useState(false);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [checkoutOpen, setCheckoutOpen] = useState(false);

  // Carrega produtos do backend (com fallback)
  const loadProducts = useCallback(async () => {
    setProductsLoading(true);
    setProductsError(null);
    try {
      const normalizeP = (p) => ({
        id: p.id,
        slug: p.slug,
        name: p.name,
        price_cents: p.price_cents,
        category: p.category || null,
        tag: (p.category || "DROPX").toUpperCase(),
        image_url: p.image_url,
        colors: Array.isArray(p.colors) && p.colors.length ? p.colors : null,
        fulfillment: p.fulfillment || "on_demand",
        stock: p.stock || null,
        variants: (p.variants || [])
      });
      const { products } = await window.dropxApi.products.list({ drop: "drop-01" });
      let normalized = (products || []).map(normalizeP).filter(p => p.variants.length > 0);
      if (!normalized.length) {
        const { products: all } = await window.dropxApi.products.list({});
        normalized = (all || []).map(normalizeP).filter(p => p.variants.length > 0);
      }
      setProducts(normalized.length ? normalized : STATIC_FALLBACK);
    } catch (e) {
      console.warn("[cart] falha ao carregar produtos, usando fallback:", e.message);
      setProductsError(e.message);
      setProducts(STATIC_FALLBACK);
    } finally {
      setProductsLoading(false);
    }
  }, []);

  useEffect(() => { loadProducts(); }, [loadProducts]);

  // Persiste carrinho
  useEffect(() => {
    try { localStorage.setItem("dropx_cart", JSON.stringify(items)); } catch {}
  }, [items]);

  const addItem = useCallback((product, variant, color) => {
    // Bloqueia se a combinação (cor+tamanho) está esgotada
    const avail = getStock(product, color ? color.id : null, variant ? variant.size : null);
    if (avail === 0) return;
    setItems((prev) => {
      const variantKey = variant.id != null ? `v${variant.id}` : `s${variant.size}`;
      const colorKey = color ? `c${color.id}` : "c0";
      const key = `${product.id}::${colorKey}::${variantKey}`;
      const found = prev.find((it) => it.key === key);
      if (found) {
        // Não ultrapassa o estoque disponível
        const nextQty = avail === Infinity ? found.qty + 1 : Math.min(avail, found.qty + 1);
        return prev.map((it) => it.key === key ? { ...it, qty: nextQty } : it);
      }
      return [...prev, {
        key,
        product_id: product.id,
        variant_id: variant.id || null,
        slug: product.slug,
        name: product.name,
        size: variant.size || "",
        color_id: color ? color.id : null,
        color_name: color ? color.name : "",
        color_hex: color ? color.hex : null,
        image_url: (color && color.image_url) || product.image_url || null,
        price_cents: product.price_cents,
        fulfillment: product.fulfillment || "on_demand",
        max_stock: avail === Infinity ? null : avail,
        qty: 1
      }];
    });
    setDrawerOpen(true);
  }, []);

  const setQty = useCallback((key, qty) => {
    setItems((prev) => {
      if (qty <= 0) return prev.filter((it) => it.key !== key);
      return prev.map((it) => {
        if (it.key !== key) return it;
        const cap = it.max_stock != null ? it.max_stock : Infinity;
        return { ...it, qty: Math.min(qty, cap) };
      });
    });
  }, []);
  const removeItem = useCallback((key) => setItems((prev) => prev.filter((it) => it.key !== key)), []);
  const clear = useCallback(() => setItems([]), []);

  const count = useMemo(() => items.reduce((s, it) => s + it.qty, 0), [items]);
  const subtotal_cents = useMemo(() => items.reduce((s, it) => s + it.qty * it.price_cents, 0), [items]);
  // legacy aliases pra outros componentes
  const total = subtotal_cents / 100;

  return (
    <CartCtx.Provider value={{
      items, count, total, subtotal_cents,
      addItem, setQty, removeItem, clear,
      catalogOpen, setCatalogOpen,
      drawerOpen, setDrawerOpen,
      checkoutOpen, setCheckoutOpen,
      products, productsLoading, productsError, reloadProducts: loadProducts
    }}>
      {children}
    </CartCtx.Provider>
  );
}

// ── HELPERS ──────────────────────────────────────────────────────────────────
const fmtCents = (c) => "R$ " + (c / 100).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });

// ── CART BUTTON (nav) ────────────────────────────────────────────────────────
function CartButton() {
  const cart = useCart();
  if (!cart) return null;
  return (
    <button
      type="button"
      className="cart-btn"
      onClick={() => cart.setDrawerOpen(true)}
      aria-label={`Abrir carrinho (${cart.count} itens)`}
    >
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 3h2l.4 2M7 13h10l4-8H5.4" />
        <circle cx="9" cy="20" r="1.5" />
        <circle cx="17" cy="20" r="1.5" />
      </svg>
      <span className="cart-count">{cart.count}</span>
    </button>
  );
}

// ── PRODUCT CARD ─────────────────────────────────────────────────────────────
// Cores e tamanhos são dimensões independentes. Trocar a cor troca a foto
// (cada cor pode ter sua própria `image_url`). Cor + tamanho = item único no
// carrinho — comprar o mesmo modelo em duas cores gera duas linhas.
//
// Estoque é por (cor × tamanho). Produtos "on_demand" são ilimitados (45 dias).
// Produtos "ready" leem o estoque da matriz do produto + overrides do admin.
function CatalogCard({ product, index }) {
  const cart = useCart();
  const colors = Array.isArray(product.colors) && product.colors.length ? product.colors : null;
  const [color, setColor] = useState(colors ? colors[0] : null);
  const [variant, setVariant] = useState(product.variants[0]);
  // re-render quando o admin mudar o estoque
  const [, setStockTick] = useState(0);
  useEffect(() => {
    const h = () => setStockTick(t => t + 1);
    window.addEventListener(STOCK_EVENT, h);
    window.addEventListener("storage", h);
    return () => { window.removeEventListener(STOCK_EVENT, h); window.removeEventListener("storage", h); };
  }, []);
  const needsSize = product.variants.length > 1;

  const onDemand = color
    ? (color.fulfillment || product.fulfillment) === "on_demand"
    : product.fulfillment === "on_demand";
  const curStock = variant ? getStock(product, color ? color.id : null, variant.size) : 0;
  const colorOut = color ? colorTotalStock(product, color.id) === 0 : false;
  const stockState = onDemand ? "on_demand"
    : curStock === 0 ? "out"
    : curStock <= LOW_STOCK_THRESHOLD ? "low"
    : "ok";

  // Imagem exibida segue a cor escolhida; cai pro produto se a cor não tem foto.
  const displayImage = (color && color.image_url) || product.image_url || null;
  const tint = color ? color.hex : "#2a211a";

  return (
    <div className={`cat-card${colorOut ? " is-out" : ""}`}>
      <div className="cat-tag-row">
        <span className="cat-tag">{product.tag} / {String((index ?? 0) + 1).padStart(2, "0")}</span>
        <span className={`cat-fulfill mono ${onDemand ? "cat-fulfill-demand" : "cat-fulfill-ready"}`}>
          {onDemand ? "SOB ENCOMENDA · 45D" : "PRONTA ENTREGA"}
        </span>
      </div>
      <div className="cat-img">
        {displayImage ? (
          <img
            key={color ? color.id : "default"}
            src={displayImage}
            alt={`${product.name} — ${color ? color.name : ""}`}
            style={{ width: "100%", height: "100%", objectFit: "cover", position: "absolute", inset: 0 }}
          />
        ) : (
          <React.Fragment>
            <div
              key={color ? color.id : "default"}
              className="cat-img-tint"
              style={{ background: `radial-gradient(circle at 30% 30%, ${tint} 0%, ${tint} 55%, rgba(0,0,0,0.45) 100%)` }}
            />
            <span className="cat-img-ph">
              [ FOTO {color ? color.name.toUpperCase() : "DO PRODUTO"} ]
            </span>
          </React.Fragment>
        )}
        {colorOut && <span className="cat-img-badge mono">ESGOTADO</span>}
      </div>
      <div className="cat-meta">
        <div className="cat-name display">{product.name}</div>
        <div className="cat-price mono">{fmtCents(product.price_cents)}</div>
      </div>
      {colors && (
        <div className="cat-colors">
          <span className="cat-colors-label mono">
            COR <strong style={{ color: "var(--fg)", marginLeft: 6 }}>{color ? color.name : ""}</strong>
          </span>
          <div className="cat-colors-row">
            {colors.map((c) => {
              const cOut = colorTotalStock(product, c.id) === 0;
              return (
                <button
                  key={c.id}
                  type="button"
                  title={cOut ? `${c.name} — esgotado` : c.name}
                  aria-label={`Cor ${c.name}${cOut ? " (esgotado)" : ""}`}
                  aria-pressed={color && color.id === c.id}
                  className={`color-swatch${color && color.id === c.id ? " active" : ""}${cOut ? " out" : ""}`}
                  style={{ background: c.hex }}
                  onClick={() => setColor(c)}
                />
              );
            })}
          </div>
        </div>
      )}
      {needsSize && (
        <div className="cat-sizes">
          {product.variants.map((v) => {
            const s = getStock(product, color ? color.id : null, v.size);
            const out = s === 0;
            return (
              <button
                key={v.id ?? v.size}
                type="button"
                className={`size-btn${variant === v ? " active" : ""}${out ? " out" : ""}`}
                onClick={() => setVariant(v)}
                title={out ? "Esgotado" : (s !== Infinity ? `${s} em estoque` : "Sob encomenda")}
              >
                {v.size}
                {out && <span className="size-strike" />}
              </button>
            );
          })}
        </div>
      )}
      <div className={`cat-stock mono stock-${stockState}`}>
        {stockState === "on_demand" && <React.Fragment>● ENCOMENDA · ~45 DIAS</React.Fragment>}
        {stockState === "ok" && <React.Fragment>● {curStock} EM ESTOQUE</React.Fragment>}
        {stockState === "low" && <React.Fragment>● ÚLTIMAS {curStock} {curStock === 1 ? "PEÇA" : "PEÇAS"}</React.Fragment>}
        {stockState === "out" && <React.Fragment>● ESGOTADO NESSE TAMANHO</React.Fragment>}
      </div>
      <button
        type="button"
        className="btn btn-primary cat-add"
        disabled={!variant || curStock === 0}
        onClick={() => cart.addItem(product, variant, color)}
      >
        {curStock === 0 ? "ESGOTADO" : (
          <React.Fragment>
            ADICIONAR{color ? ` ${color.name.toUpperCase()}` : ""}{needsSize && variant ? ` · ${variant.size}` : ""}
          </React.Fragment>
        )}
      </button>
    </div>
  );
}

// ── DROP CATALOG ─────────────────────────────────────────────────────────────
// Ordem preferida de categorias (as não-mapeadas vão pro final, em ordem alfabética).
const CATEGORY_ORDER = ["Camiseta", "Moletom", "Calça", "Shorts", "Tênis", "Jaqueta", "Casaco", "Bolsa", "Boné", "Acessório"];
function categoryOf(p) {
  return p.category || (p.tag ? (p.tag.charAt(0) + p.tag.slice(1).toLowerCase()) : "Outros");
}

function DropCatalog() {
  const cart = useCart();
  const [activeCat, setActiveCat] = useState("all");
  const [query, setQuery] = useState("");
  useEffect(() => {
    document.body.style.overflow = cart.catalogOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [cart.catalogOpen]);
  // Limpa busca ao fechar o modal
  useEffect(() => { if (!cart.catalogOpen) setQuery(""); }, [cart.catalogOpen]);

  // Aplica busca textual primeiro (nome, categoria, cor) — categorias e contagens
  // refletem só o que casa com a busca.
  const searched = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return cart.products;
    const tokens = q.split(/\s+/).filter(Boolean);
    return cart.products.filter(p => {
      const hay = [
        p.name, p.slug, p.tag, p.category,
        ...(Array.isArray(p.colors) ? p.colors.map(c => c.name + " " + c.id) : [])
      ].filter(Boolean).join(" ").toLowerCase();
      return tokens.every(t => hay.includes(t));
    });
  }, [cart.products, query]);

  // Categorias presentes nos produtos (com contagem), ordenadas
  const categories = useMemo(() => {
    const counts = new Map();
    for (const p of searched) {
      const c = categoryOf(p);
      counts.set(c, (counts.get(c) || 0) + 1);
    }
    const ordered = [];
    for (const k of CATEGORY_ORDER) if (counts.has(k)) ordered.push({ name: k, count: counts.get(k) });
    const extras = Array.from(counts.keys()).filter(k => !CATEGORY_ORDER.includes(k)).sort();
    for (const k of extras) ordered.push({ name: k, count: counts.get(k) });
    return ordered;
  }, [searched]);

  // Quando o catálogo abre, garante que a categoria ativa ainda existe
  useEffect(() => {
    if (activeCat === "all") return;
    if (!categories.find(c => c.name === activeCat)) setActiveCat("all");
  }, [categories, activeCat]);

  const filteredProducts = useMemo(() => {
    if (activeCat === "all") return searched;
    return searched.filter(p => categoryOf(p) === activeCat);
  }, [searched, activeCat]);

  if (!cart.catalogOpen) return null;
  return (
    <div className="cat-overlay" onClick={(e) => { if (e.target === e.currentTarget) cart.setCatalogOpen(false); }}>
      <div className="cat-modal">
        {/* Topo: categorias (tab bar) + ações */}
        <div className="cat-topbar">
          {categories.length > 1 ? (
            <nav className="cat-cats" aria-label="Filtrar por categoria">
              <button
                type="button"
                className={`cat-cat-btn mono${activeCat === "all" ? " active" : ""}`}
                onClick={() => setActiveCat("all")}
              >
                TUDO <span className="cat-cat-count">{searched.length}</span>
              </button>
              {categories.map(c => (
                <button
                  key={c.name}
                  type="button"
                  className={`cat-cat-btn mono${activeCat === c.name ? " active" : ""}`}
                  onClick={() => setActiveCat(c.name)}
                >
                  {c.name.toUpperCase()} <span className="cat-cat-count">{c.count}</span>
                </button>
              ))}
            </nav>
          ) : <div />}
          <div className="cat-topbar-right">
            <button type="button" className="cat-btn-cart" onClick={() => cart.setDrawerOpen(true)}>
              CARRINHO ({cart.count})
            </button>
            <button type="button" className="cat-close" onClick={() => cart.setCatalogOpen(false)} aria-label="Fechar">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                <line x1="6" y1="6" x2="18" y2="18" />
                <line x1="18" y1="6" x2="6" y2="18" />
              </svg>
            </button>
          </div>
        </div>

        {/* Barra de busca */}
        <div className="cat-search-wrap">
          <div className="cat-search">
            <svg className="cat-search-ic" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <circle cx="11" cy="11" r="7" />
              <line x1="21" y1="21" x2="16.65" y2="16.65" />
            </svg>
            <input
              type="search"
              className="cat-search-input"
              placeholder="Buscar item, cor, categoria…"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              autoComplete="off"
              aria-label="Buscar itens do drop"
            />
            {query && (
              <button
                type="button"
                className="cat-search-clear mono"
                onClick={() => setQuery("")}
                aria-label="Limpar busca"
              >
                LIMPAR
              </button>
            )}
          </div>
          {query && (
            <span className="cat-search-meta mono">
              {searched.length} {searched.length === 1 ? "RESULTADO" : "RESULTADOS"}
            </span>
          )}
        </div>

        {/* Cabeçalho compacto do drop */}
        <header className="cat-head">
          <div className="cat-head-left">
            <span className="mono cat-head-mono">DROP #01 · ABERTO</span>
            <h2 className="display cat-head-title">
              {activeCat === "all" ? "Itens do drop atual." : activeCat + "."}
            </h2>
            {cart.productsError && (
              <span className="cat-head-warn mono">⚠ Catálogo em modo offline (backend indisponível).</span>
            )}
          </div>
          <div className="cat-head-meta mono">
            PIX OU CARTÃO · ~45 DIAS · FORNECEDOR VALIDADO
          </div>
        </header>

        {/* Grid de produtos — ocupa o espaço restante */}
        <div className="cat-grid">
          {cart.productsLoading && <div className="cat-img-ph" style={{ gridColumn: "1/-1", padding: 60, textAlign: "center" }}>Carregando catálogo…</div>}
          {!cart.productsLoading && filteredProducts.length === 0 && (
            <div className="cat-img-ph" style={{ gridColumn: "1/-1", padding: 60, textAlign: "center" }}>
              {query
                ? `Nenhum item encontrado para "${query}".`
                : "Nenhum item nessa categoria."}
            </div>
          )}
          {!cart.productsLoading && filteredProducts.map((p, i) => <CatalogCard key={p.id} product={p} index={i} />)}
        </div>
        {cart.count > 0 && (
          <footer className="cat-foot">
            <span className="mono cat-foot-meta">{cart.count} {cart.count === 1 ? "ITEM" : "ITENS"} NO CARRINHO</span>
            <button type="button" className="btn btn-primary" onClick={() => cart.setDrawerOpen(true)}>
              VER CARRINHO →
            </button>
          </footer>
        )}
      </div>
    </div>
  );
}

// ── CART DRAWER ──────────────────────────────────────────────────────────────
function CartDrawer() {
  const cart = useCart();
  useEffect(() => {
    if (cart.drawerOpen) document.body.style.overflow = "hidden";
    else if (!cart.catalogOpen) document.body.style.overflow = "";
  }, [cart.drawerOpen, cart.catalogOpen]);
  if (!cart.drawerOpen) return null;
  return (
    <div className="drw-overlay" onClick={(e) => { if (e.target === e.currentTarget) cart.setDrawerOpen(false); }}>
      <aside className="drw">
        <header className="drw-head">
          <div>
            <span className="mono drw-head-mono">SEU CARRINHO</span>
            <div className="drw-head-title display">DROP #01</div>
          </div>
          <button type="button" className="cat-close" onClick={() => cart.setDrawerOpen(false)} aria-label="Fechar">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
              <line x1="6" y1="6" x2="18" y2="18" />
              <line x1="18" y1="6" x2="6" y2="18" />
            </svg>
          </button>
        </header>

        {cart.items.length === 0 ? (
          <div className="drw-empty">
            <div className="drw-empty-mark display">∅</div>
            <p className="drw-empty-t display">Carrinho vazio.</p>
            <p className="drw-empty-d">Abre o catálogo do Drop #01 e escolhe suas peças.</p>
            <button type="button" className="btn btn-primary" onClick={() => { cart.setDrawerOpen(false); cart.setCatalogOpen(true); }}>
              VER ITENS DO DROP →
            </button>
          </div>
        ) : (
          <React.Fragment>
            <div className="drw-list">
              {cart.items.map((it) => (
                <div className="drw-item" key={it.key}>
                  <div className="drw-item-img" style={it.color_hex ? { background: it.color_hex, color: "rgba(255,255,255,0.85)" } : undefined}>
                    {it.image_url
                      ? <img src={it.image_url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover", borderRadius: 4 }} />
                      : <span>{it.name.slice(0,1)}</span>}
                  </div>
                  <div className="drw-item-mid">
                    <div className="drw-item-name display">{it.name}</div>
                    <div className="drw-item-size mono">
                      {it.color_name && (
                        <React.Fragment>
                          <span className="drw-item-dot" style={it.color_hex ? { background: it.color_hex } : undefined} />
                          {it.color_name.toUpperCase()}
                          {it.size ? " · " : ""}
                        </React.Fragment>
                      )}
                      {it.size && <React.Fragment>TAM {it.size}</React.Fragment>}
                    </div>
                    <div className="drw-item-qty">
                      <button type="button" onClick={() => cart.setQty(it.key, it.qty - 1)} aria-label="Diminuir">−</button>
                      <span>{it.qty}</span>
                      <button type="button" onClick={() => cart.setQty(it.key, it.qty + 1)} aria-label="Aumentar">+</button>
                      <button type="button" className="drw-item-rm mono" onClick={() => cart.removeItem(it.key)}>REMOVER</button>
                    </div>
                  </div>
                  <div className="drw-item-price mono">{fmtCents(it.qty * it.price_cents)}</div>
                </div>
              ))}
            </div>

            <div className="drw-info mono">
              ⓘ Prazo médio de chegada: ~45 dias. Pagamento via Pix (na hora) ou cartão (Mercado Pago).
              Você acompanha o pedido pelo código de rastreio enviado por e-mail.
            </div>

            <footer className="drw-foot">
              <div className="drw-totals">
                <div className="drw-row mono"><span>SUBTOTAL</span><span>{fmtCents(cart.subtotal_cents)}</span></div>
                <div className="drw-row mono"><span>FRETE</span><span>A COMBINAR</span></div>
                <div className="drw-row drw-total"><span>TOTAL</span><span>{fmtCents(cart.subtotal_cents)}</span></div>
              </div>
              <a className="btn btn-primary drw-checkout" href="#" onClick={(e) => { e.preventDefault(); cart.setDrawerOpen(false); cart.setCheckoutOpen(true); }}>
                FINALIZAR PEDIDO →
              </a>
              <button type="button" className="drw-clear mono" onClick={() => { if (confirm("Esvaziar carrinho?")) cart.clear(); }}>
                ESVAZIAR CARRINHO
              </button>
            </footer>
          </React.Fragment>
        )}
      </aside>
    </div>
  );
}

Object.assign(window, { CartProvider, useCart, CartButton, DropCatalog, CartDrawer, fmtCents,
  getStock, colorTotalStock, readStockOverrides, writeStockOverride,
  STOCK_OVERRIDES_KEY, STOCK_EVENT, LOW_STOCK_THRESHOLD, STATIC_FALLBACK });
