// MerchPage.jsx — Shopify Storefront-backed product grid + cart drawer.
// Config lives in config/shopify.js (window.SHOPIFY_CONFIG). Setup guide: SHOPIFY_PRINTFUL_SETUP.md.

const SHOPIFY_CHECKOUT_KEY = 'warpedbbq.shopify.checkoutId';

const buildShopifyClient = () => {
  const cfg = window.SHOPIFY_CONFIG || {};
  if (!window.ShopifyBuy || !cfg.domain || !cfg.storefrontAccessToken) return null;
  try {
    return window.ShopifyBuy.buildClient({
      domain: cfg.domain,
      storefrontAccessToken: cfg.storefrontAccessToken,
    });
  } catch (e) { return null; }
};

// Map Shopify productType → accent color so cards keep the mascot-era vibe
const typeColor = (productType) => {
  const t = (productType || '').toLowerCase();
  if (t.includes('hood')) return 'var(--wbbq-flame-hot)';
  if (t.includes('hat')) return 'var(--wbbq-slime)';
  if (t.includes('poster')) return 'var(--wbbq-blue)';
  if (t.includes('sticker')) return 'var(--wbbq-pig)';
  if (t.includes('tee') || t.includes('shirt')) return 'var(--wbbq-flame)';
  return 'var(--wbbq-flame)';
};

const centsToPrice = (amount) => {
  const n = parseFloat(amount);
  return Number.isFinite(n) ? `$${n.toFixed(n % 1 === 0 ? 0 : 2)}` : '—';
};

const MerchPage = () => {
  useReveal();
  const [filter, setFilter] = useState('ALL');
  const [products, setProducts] = useState(null); // null = loading, [] = loaded empty
  const [error, setError] = useState(null);
  const [checkout, setCheckout] = useState(null);
  const [cartOpen, setCartOpen] = useState(false);
  const [busyId, setBusyId] = useState(null);

  const client = useMemo(() => buildShopifyClient(), []);
  const configured = !!client;

  // Load products (by collection handle or all)
  useEffect(() => {
    if (!client) { setProducts([]); return; }
    const cfg = window.SHOPIFY_CONFIG || {};
    const loader = cfg.collectionHandle
      ? client.collection.fetchByHandle(cfg.collectionHandle).then(c => c ? c.products : [])
      : client.product.fetchAll(60);
    loader.then(list => setProducts(list || [])).catch(e => {
      console.error('Shopify fetch failed', e);
      setError(e.message || 'Could not load products');
      setProducts([]);
    });
  }, [client]);

  // Bootstrap checkout (create or restore)
  useEffect(() => {
    if (!client) return;
    const existingId = localStorage.getItem(SHOPIFY_CHECKOUT_KEY);
    const onReady = (c) => {
      if (!c || c.completedAt) {
        client.checkout.create().then(fresh => {
          localStorage.setItem(SHOPIFY_CHECKOUT_KEY, fresh.id);
          setCheckout(fresh);
        });
      } else {
        setCheckout(c);
      }
    };
    if (existingId) {
      client.checkout.fetch(existingId).then(onReady).catch(() => onReady(null));
    } else {
      onReady(null);
    }
  }, [client]);

  const productTypes = useMemo(() => {
    if (!products) return ['ALL'];
    const set = new Set();
    products.forEach(p => { if (p.productType) set.add(p.productType.toUpperCase()); });
    return ['ALL', ...Array.from(set).sort()];
  }, [products]);

  const shown = useMemo(() => {
    if (!products) return [];
    if (filter === 'ALL') return products;
    return products.filter(p => (p.productType || '').toUpperCase() === filter);
  }, [products, filter]);

  const addToCart = (product) => {
    if (!client || !checkout) return;
    const variant = product.variants && product.variants.find(v => v.available) || (product.variants && product.variants[0]);
    if (!variant) return;
    setBusyId(product.id);
    client.checkout.addLineItems(checkout.id, [{ variantId: variant.id, quantity: 1 }])
      .then(updated => { setCheckout(updated); setCartOpen(true); })
      .catch(e => console.error('addLineItems failed', e))
      .finally(() => setBusyId(null));
  };

  const updateQty = (lineItemId, quantity) => {
    if (!client || !checkout) return;
    if (quantity <= 0) {
      client.checkout.removeLineItems(checkout.id, [lineItemId]).then(setCheckout);
    } else {
      client.checkout.updateLineItems(checkout.id, [{ id: lineItemId, quantity }]).then(setCheckout);
    }
  };

  const cartItemCount = checkout ? checkout.lineItems.reduce((a, li) => a + li.quantity, 0) : 0;

  return (
    <>
      <PageHero eyebrow="The Drop" title={<>Wear The <span style={{ color: 'var(--wbbq-flame)' }}>Pig.</span></>} subtitle="Printed on good stuff. Shipped via Printful worldwide. No refunds for taste." mascot="pig.svg" />
      <section className="section">
        <div className="wrap">
          {!configured && <ShopifyNotConfigured />}
          {configured && (
            <>
              <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginBottom: 36, paddingBottom: 20, borderBottom: '2px solid var(--border)' }}>
                {productTypes.map(t => (
                  <button key={t} onClick={() => setFilter(t)} style={{
                    fontFamily: 'var(--font-display)', fontSize: 12, letterSpacing: '0.1em',
                    padding: '10px 16px',
                    background: filter === t ? 'var(--wbbq-flame)' : 'transparent',
                    color: filter === t ? 'var(--wbbq-black)' : 'var(--fg1)',
                    border: '2px solid ' + (filter === t ? 'var(--wbbq-flame)' : 'var(--border)'),
                    textTransform: 'uppercase', cursor: 'pointer',
                    transition: 'all 120ms',
                  }}>{t}</button>
                ))}
              </div>

              {products === null && <LoadingState />}
              {products !== null && error && <ErrorState msg={error} />}
              {products !== null && !error && shown.length === 0 && <EmptyState />}

              {shown.length > 0 && (
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(260px, 1fr))', gap: 28 }}>
                  {shown.map((p, i) => <ProductCard key={p.id} product={p} busy={busyId === p.id} onAdd={() => addToCart(p)} rot={`${((i % 3) - 1) * 0.8}deg`} />)}
                </div>
              )}

              <div style={{ marginTop: 48, padding: 20, background: 'var(--wbbq-ink)', border: '2px dashed var(--border)', textAlign: 'center', color: 'var(--fg2)', fontSize: 13 }}>
                <span style={{ color: 'var(--wbbq-flame)', fontWeight: 800, letterSpacing: '0.1em', textTransform: 'uppercase' }}>PRINTED ON DEMAND</span> · shipped from the closest Printful facility · 5–10 biz days.
              </div>
            </>
          )}
        </div>
      </section>

      {configured && (
        <>
          <CartButton count={cartItemCount} onClick={() => setCartOpen(true)} />
          <CartDrawer open={cartOpen} onClose={() => setCartOpen(false)} checkout={checkout} onQty={updateQty} />
        </>
      )}
    </>
  );
};

const ProductCard = ({ product, busy, onAdd, rot }) => {
  const color = typeColor(product.productType);
  const img = product.images && product.images[0];
  const variant = product.variants && (product.variants.find(v => v.available) || product.variants[0]);
  const available = variant && variant.available;
  const price = variant ? parseFloat(variant.price.amount || variant.price) : null;
  return (
    <div className="reveal" style={{ rotate: rot }}>
      <div style={{
        position: 'relative',
        background: 'var(--wbbq-ink)', border: `3px solid ${color}`,
        padding: 20,
        transition: 'all 220ms var(--ease-snap)',
      }}
      onMouseEnter={(e) => { e.currentTarget.style.transform = 'translate(-3px,-3px)'; e.currentTarget.style.boxShadow = `10px 10px 0 ${color}`; }}
      onMouseLeave={(e) => { e.currentTarget.style.transform = 'translate(0,0)'; e.currentTarget.style.boxShadow = 'none'; }}
      >
        <div style={{
          position: 'absolute', top: 14, right: 14,
          fontFamily: 'var(--font-mono)', fontSize: 10,
          padding: '4px 8px', background: available ? color : 'var(--border)', color: available ? 'var(--wbbq-black)' : 'var(--fg2)',
          fontWeight: 700, letterSpacing: '0.1em',
        }}>{available ? 'IN STOCK' : 'SOLD OUT'}</div>
        <div style={{ aspectRatio: '1/1', background: 'var(--wbbq-black)', display: 'grid', placeItems: 'center', padding: 16, border: '2px dashed var(--border)', position: 'relative', overflow: 'hidden' }}>
          <div className="halftone" style={{ position: 'absolute', inset: 0, opacity: 0.3 }} />
          {img ? (
            <img src={img.src} alt={product.title} style={{ maxHeight: '94%', maxWidth: '94%', position: 'relative', zIndex: 1, objectFit: 'contain' }} />
          ) : (
            <div style={{ color: 'var(--fg3)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>no image</div>
          )}
        </div>
        <div style={{ marginTop: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'end', gap: 12 }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 14, letterSpacing: '0.04em', color: 'var(--wbbq-bone)', textTransform: 'uppercase', flex: 1, lineHeight: 1.15 }}>{product.title}</div>
          <div style={{ fontFamily: 'var(--font-mono)', color, fontSize: 18, fontWeight: 700, whiteSpace: 'nowrap' }}>{price !== null ? centsToPrice(price) : '—'}</div>
        </div>
        <button disabled={!available || busy} onClick={onAdd} style={{
          marginTop: 14, width: '100%',
          padding: '10px 12px',
          background: busy ? color : 'transparent',
          color: busy ? 'var(--wbbq-black)' : (available ? 'var(--fg1)' : 'var(--fg3)'),
          border: `2px solid ${available ? 'var(--border)' : 'var(--border)'}`,
          fontFamily: 'var(--font-display)', fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase',
          cursor: available && !busy ? 'pointer' : 'not-allowed',
          opacity: available ? 1 : 0.5,
          transition: 'all 120ms',
        }}
        onMouseEnter={(e) => { if (available && !busy) { e.currentTarget.style.background = color; e.currentTarget.style.color = 'var(--wbbq-black)'; e.currentTarget.style.borderColor = color; } }}
        onMouseLeave={(e) => { if (!busy) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = available ? 'var(--fg1)' : 'var(--fg3)'; e.currentTarget.style.borderColor = 'var(--border)'; } }}
        >
          {!available ? 'Sold Out' : busy ? 'Adding…' : 'Add to Cart →'}
        </button>
      </div>
    </div>
  );
};

const CartButton = ({ count, onClick }) => (
  <button onClick={onClick} style={{
    position: 'fixed', bottom: 24, right: 24, zIndex: 90,
    background: 'var(--wbbq-flame)', color: 'var(--wbbq-black)',
    border: 'none',
    padding: '14px 20px',
    fontFamily: 'var(--font-display)', fontSize: 13, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 800,
    cursor: 'pointer',
    boxShadow: '6px 6px 0 var(--wbbq-blue)',
    display: 'flex', alignItems: 'center', gap: 10,
  }}>
    Cart
    <span style={{
      display: 'inline-grid', placeItems: 'center',
      minWidth: 22, height: 22, padding: '0 6px',
      background: 'var(--wbbq-black)', color: 'var(--wbbq-flame)',
      fontFamily: 'var(--font-mono)', fontSize: 12,
    }}>{count}</span>
  </button>
);

const CartDrawer = ({ open, onClose, checkout, onQty }) => {
  if (!open) return null;
  const lineItems = checkout ? checkout.lineItems : [];
  const subtotal = checkout ? parseFloat(checkout.subtotalPrice.amount || checkout.subtotalPrice) : 0;
  const hasItems = lineItems.length > 0;
  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 95, display: 'flex', justifyContent: 'flex-end' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.65)' }} />
      <div style={{
        position: 'relative', width: 'min(440px, 100vw)', background: 'var(--wbbq-ink)',
        borderLeft: '3px solid var(--wbbq-flame)',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '20px 24px', borderBottom: '1px solid var(--border)' }}>
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 20, letterSpacing: '0.06em', color: 'var(--wbbq-bone)' }}>
            Cart <span style={{ color: 'var(--fg3)', fontFamily: 'var(--font-mono)', fontSize: 13 }}>({lineItems.reduce((a, li) => a + li.quantity, 0)})</span>
          </div>
          <button onClick={onClose} style={{ background: 'transparent', border: 'none', color: 'var(--fg1)', fontSize: 20, cursor: 'pointer' }}>✕</button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '16px 24px' }}>
          {!hasItems && <div style={{ color: 'var(--fg3)', fontSize: 14, padding: '40px 0', textAlign: 'center', fontStyle: 'italic' }}>Empty.</div>}
          {lineItems.map(li => (
            <div key={li.id} style={{ display: 'grid', gridTemplateColumns: '60px 1fr auto', gap: 14, alignItems: 'center', padding: '14px 0', borderBottom: '1px dashed var(--border)' }}>
              {li.variant && li.variant.image && <img src={li.variant.image.src} alt="" style={{ width: 60, height: 60, objectFit: 'cover', background: 'var(--wbbq-black)' }} />}
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: 'var(--font-display)', fontSize: 13, color: 'var(--wbbq-bone)', textTransform: 'uppercase', letterSpacing: '0.04em', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{li.title}</div>
                {li.variantTitle && li.variantTitle !== 'Default Title' && (
                  <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--fg3)', marginTop: 2 }}>{li.variantTitle}</div>
                )}
                <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginTop: 6 }}>
                  <button onClick={() => onQty(li.id, li.quantity - 1)} style={qtyBtnStyle}>−</button>
                  <span style={{ fontFamily: 'var(--font-mono)', minWidth: 22, textAlign: 'center' }}>{li.quantity}</span>
                  <button onClick={() => onQty(li.id, li.quantity + 1)} style={qtyBtnStyle}>+</button>
                </div>
              </div>
              <div style={{ fontFamily: 'var(--font-mono)', color: 'var(--wbbq-flame)', fontSize: 14, fontWeight: 700 }}>
                ${(parseFloat(li.variant.price.amount || li.variant.price) * li.quantity).toFixed(2)}
              </div>
            </div>
          ))}
        </div>
        {hasItems && (
          <div style={{ padding: '18px 24px', borderTop: '1px solid var(--border)', background: 'var(--wbbq-black)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14 }}>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 11, letterSpacing: '0.18em', color: 'var(--fg3)', textTransform: 'uppercase' }}>Subtotal</div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 22, color: 'var(--wbbq-flame)' }}>${subtotal.toFixed(2)}</div>
            </div>
            <a href={checkout.webUrl} target="_top" style={{
              display: 'block', textAlign: 'center',
              padding: '14px 18px',
              background: 'var(--wbbq-flame)', color: 'var(--wbbq-black)',
              fontFamily: 'var(--font-display)', fontSize: 14, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 800,
              textDecoration: 'none',
              border: '2px solid var(--wbbq-flame)',
            }}>Checkout →</a>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--fg3)', textAlign: 'center', marginTop: 10 }}>
              Taxes + shipping calculated at checkout.
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

const qtyBtnStyle = {
  width: 24, height: 24, background: 'var(--wbbq-black)', color: 'var(--fg1)',
  border: '1px solid var(--border)', cursor: 'pointer',
  fontFamily: 'var(--font-mono)', fontSize: 14, lineHeight: 1,
};

const LoadingState = () => (
  <div style={{ padding: 60, textAlign: 'center', color: 'var(--fg3)', fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.1em' }}>
    LOADING PRODUCTS…
  </div>
);

const EmptyState = () => (
  <div style={{ padding: 40, textAlign: 'center', border: '2px dashed var(--border)', background: 'var(--wbbq-ink)', color: 'var(--fg2)' }}>
    No products in this category yet. Check back soon.
  </div>
);

const ErrorState = ({ msg }) => (
  <div style={{ padding: 20, border: '2px solid var(--wbbq-blood)', background: 'var(--wbbq-ink)', color: 'var(--fg1)' }}>
    <div style={{ fontFamily: 'var(--font-display)', fontSize: 13, letterSpacing: '0.14em', color: 'var(--wbbq-blood)', textTransform: 'uppercase', marginBottom: 8 }}>Store Error</div>
    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg2)' }}>{msg}</div>
  </div>
);

const ShopifyNotConfigured = () => (
  <div style={{ padding: 32, border: '2px dashed var(--wbbq-flame)', background: 'var(--wbbq-ink)', color: 'var(--fg1)' }}>
    <div style={{ fontFamily: 'var(--font-display)', fontSize: 13, letterSpacing: '0.14em', color: 'var(--wbbq-flame)', textTransform: 'uppercase', marginBottom: 10 }}>Store Coming Online</div>
    <div style={{ fontSize: 14, marginBottom: 10 }}>Shopify + Printful aren't wired up yet. Once <code style={{ color: 'var(--wbbq-slime)' }}>config/shopify.js</code> has a store domain and Storefront API token, this grid populates automatically.</div>
    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg3)' }}>See <code style={{ color: 'var(--wbbq-bone)' }}>SHOPIFY_PRINTFUL_SETUP.md</code> for the step-by-step.</div>
  </div>
);

window.MerchPage = MerchPage;
