/* =========================================================
   Shop — cart store, cart surfaces, checkout, confirmation
   ========================================================= */

const { useState: useShopState, useEffect: useShopEffect, useMemo: useShopMemo, useCallback: useShopCallback, useRef: useShopRef } = React;

const CART_KEY = 'clarion_cart';
const ORDER_KEY = 'clarion_last_order';

/* ---------- useCart hook ---------- */
function useCart() {
  const [items, setItems] = useShopState(() => {
    try { return JSON.parse(localStorage.getItem(CART_KEY) || '[]'); } catch { return []; }
  });

  // Persist + broadcast only when items actually differ from what's stored.
  useShopEffect(() => {
    const serialized = JSON.stringify(items);
    const stored = localStorage.getItem(CART_KEY) || '[]';
    if (serialized === stored) return; // no-op: came from a sync or unchanged
    localStorage.setItem(CART_KEY, serialized);
    window.dispatchEvent(new CustomEvent('clarion-cart-change'));
  }, [items]);

  // Listen for external cart changes; only update if different from current state.
  useShopEffect(() => {
    const sync = () => {
      try {
        const raw = localStorage.getItem(CART_KEY) || '[]';
        setItems(prev => {
          if (JSON.stringify(prev) === raw) return prev; // same ref, no re-render
          return JSON.parse(raw);
        });
      } catch {}
    };
    window.addEventListener('clarion-cart-change', sync);
    window.addEventListener('storage', sync);
    return () => {
      window.removeEventListener('clarion-cart-change', sync);
      window.removeEventListener('storage', sync);
    };
  }, []);

  const add = (slug, qty = 1) => {
    setItems(prev => {
      const found = prev.find(i => i.slug === slug);
      if (found) return prev.map(i => i.slug === slug ? { ...i, qty: Math.min(i.qty + qty, 99) } : i);
      return [...prev, { slug, qty }];
    });
  };
  const setQty = (slug, qty) => {
    if (qty <= 0) return remove(slug);
    setItems(prev => prev.map(i => i.slug === slug ? { ...i, qty: Math.min(qty, 99) } : i));
  };
  const remove = (slug) => setItems(prev => prev.filter(i => i.slug !== slug));
  const clear = () => setItems([]);

  const lines = items.map(i => {
    const p = PRODUCTS.find(x => x.slug === i.slug);
    return p ? { ...i, product: p, lineTotal: p.price * i.qty } : null;
  }).filter(Boolean);
  const count = items.reduce((s, i) => s + i.qty, 0);
  const subtotal = lines.reduce((s, l) => s + l.lineTotal, 0);

  return { items, lines, count, subtotal, add, setQty, remove, clear };
}

/* ---------- Price helpers ---------- */
const fmt = (n) => '$' + n.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
const fmt2 = (n) => '$' + n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

/* ---------- Recently viewed ---------- */
const RV_KEY = 'clarion_recently_viewed';
function trackRecentlyViewed(slug) {
  try {
    const arr = JSON.parse(localStorage.getItem(RV_KEY) || '[]');
    const next = [slug, ...arr.filter(s => s !== slug)].slice(0, 6);
    localStorage.setItem(RV_KEY, JSON.stringify(next));
  } catch {}
}
function getRecentlyViewed(excludeSlug) {
  try {
    const arr = JSON.parse(localStorage.getItem(RV_KEY) || '[]');
    return arr.filter(s => s !== excludeSlug).map(s => PRODUCTS.find(p => p.slug === s)).filter(Boolean);
  } catch { return []; }
}

/* ---------- Urgency nudge ---------- */
// Stable per-slug viewer count so it doesn't flicker on every render
function viewersFor(slug) {
  let h = 0;
  for (let i = 0; i < slug.length; i++) h = (h * 31 + slug.charCodeAt(i)) | 0;
  return 4 + (Math.abs(h) % 17); // 4..20
}

/* =========================================================
   Cart Drawer (default surface)
   ========================================================= */
function CartDrawer({ open, onClose, go }) {
  const cart = useCart();
  const overlayRef = useShopRef();

  useShopEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [open]);

  if (!open) return null;

  const below = FREE_SHIPPING_THRESHOLD - cart.subtotal;
  const progress = Math.min(100, (cart.subtotal / FREE_SHIPPING_THRESHOLD) * 100);

  return (
    <div ref={overlayRef} className="cart-overlay" onClick={(e) => e.target === overlayRef.current && onClose()}>
      <aside className="cart-drawer" role="dialog" aria-label="Shopping cart">
        <header className="cart-drawer-head">
          <div>
            <div className="eyebrow" style={{ marginBottom: 4 }}>YOUR CART</div>
            <h3 className="cart-drawer-title">{cart.count === 0 ? 'Empty' : `${cart.count} item${cart.count > 1 ? 's' : ''}`}</h3>
          </div>
          <button className="cart-drawer-close" onClick={onClose} aria-label="Close cart">×</button>
        </header>

        {cart.count > 0 && (
          <div className="cart-drawer-ship-bar">
            {below > 0 ? (
              <div className="cart-ship-msg">Add <strong>{fmt(below)}</strong> more for <strong>free standard shipping</strong>.</div>
            ) : (
              <div className="cart-ship-msg cart-ship-msg-won">✓ You've unlocked free standard shipping.</div>
            )}
            <div className="cart-ship-progress"><div className="cart-ship-progress-bar" style={{ width: progress + '%' }} /></div>
          </div>
        )}

        <div className="cart-drawer-body">
          {cart.count === 0 ? (
            <div className="cart-empty">
              <div className="cart-empty-icon">
                <svg width="48" height="48" viewBox="0 0 48 48" fill="none" stroke="currentColor" strokeWidth="1.5">
                  <path d="M12 14h26l-3 22H15z" /><path d="M18 14v-4a6 6 0 0 1 12 0v4" />
                </svg>
              </div>
              <div className="cart-empty-title">Your cart is empty</div>
              <div className="cart-empty-body">Browse the catalog and find what your research needs.</div>
              <button className="btn btn-primary" onClick={() => { onClose(); go('catalog'); }}>Browse catalog →</button>
            </div>
          ) : cart.lines.map(line => (
            <CartLine key={line.slug} line={line} cart={cart} onOpen={(slug) => { onClose(); go('product', slug); }} />
          ))}
        </div>

        {cart.count > 0 && (
          <footer className="cart-drawer-foot">
            <div className="cart-totals-row">
              <span>Subtotal</span><span className="cart-totals-v">{fmt2(cart.subtotal)}</span>
            </div>
            <div className="cart-totals-note">Shipping and taxes calculated at checkout.</div>
            <button className="btn btn-primary cart-checkout-btn" onClick={() => { onClose(); go('checkout'); }}>
              Checkout · {fmt2(cart.subtotal)} →
            </button>
            <button className="btn-link cart-view-cart" onClick={() => { onClose(); go('cart'); }}>View full cart</button>
          </footer>
        )}
      </aside>
    </div>
  );
}

/* ---------- Shared cart line item ---------- */
function CartLine({ line, cart, onOpen, compact }) {
  const { product: p, qty, lineTotal } = line;
  return (
    <div className={"cart-line" + (compact ? ' cart-line-compact' : '')}>
      <div className="cart-line-photo" onClick={() => onOpen && onOpen(p.slug)} style={{ cursor: onOpen ? 'pointer' : 'default' }}>
        <img src="./assets/vial-photo.webp" alt={p.code} />
      </div>
      <div className="cart-line-info">
        <div className="cart-line-cat">{p.category}</div>
        <div className="cart-line-name" onClick={() => onOpen && onOpen(p.slug)} style={{ cursor: onOpen ? 'pointer' : 'default' }}>{p.code}</div>
        <div className="cart-line-specs">{p.weight} · {p.purity}</div>
        <div className="cart-line-bottom">
          <div className="qty-stepper">
            <button onClick={() => cart.setQty(p.slug, qty - 1)} aria-label="Decrease">−</button>
            <span>{qty}</span>
            <button onClick={() => cart.setQty(p.slug, qty + 1)} aria-label="Increase">+</button>
          </div>
          <button className="cart-line-remove" onClick={() => cart.remove(p.slug)}>Remove</button>
        </div>
      </div>
      <div className="cart-line-price">
        <div className="cart-line-linetotal">{fmt2(lineTotal)}</div>
        {qty > 1 && <div className="cart-line-each">{fmt(p.price)} each</div>}
      </div>
    </div>
  );
}

/* =========================================================
   Cart Overlay (top-drawer / popover)
   ========================================================= */
function CartOverlay({ open, onClose, go }) {
  const cart = useCart();
  if (!open) return null;
  return (
    <div className="cart-pop-backdrop" onClick={onClose}>
      <div className="cart-pop" onClick={e => e.stopPropagation()}>
        <div className="cart-pop-head">
          <span className="cart-pop-title">{cart.count === 0 ? 'Cart empty' : `Cart · ${cart.count} item${cart.count > 1 ? 's' : ''}`}</span>
          <button className="cart-drawer-close" onClick={onClose}>×</button>
        </div>
        {cart.count === 0 ? (
          <div style={{ padding: '24px 20px', textAlign: 'center', color: 'var(--fg2)', fontSize: 14 }}>
            Nothing here yet. <a className="btn-link" onClick={() => { onClose(); go('catalog'); }}>Browse catalog →</a>
          </div>
        ) : (
          <>
            <div className="cart-pop-body">
              {cart.lines.map(line => <CartLine key={line.slug} line={line} cart={cart} compact onOpen={(s) => { onClose(); go('product', s); }} />)}
            </div>
            <div className="cart-pop-foot">
              <div className="cart-totals-row"><span>Subtotal</span><span className="cart-totals-v">{fmt2(cart.subtotal)}</span></div>
              <button className="btn btn-primary cart-checkout-btn" onClick={() => { onClose(); go('checkout'); }}>Checkout →</button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

/* =========================================================
   Full Cart Page
   ========================================================= */
function CartPage({ go }) {
  const cart = useCart();
  if (cart.count === 0) {
    return (
      <section style={{ padding: '96px 0' }}>
        <div className="container-narrow" style={{ textAlign: 'center' }}>
          <div className="eyebrow" style={{ marginBottom: 14 }}>YOUR CART</div>
          <h1 style={{ fontSize: 48, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '0 0 16px' }}>Your cart is empty</h1>
          <p style={{ fontSize: 15, color: 'var(--fg2)', lineHeight: 1.6, marginBottom: 32 }}>Six research-grade compounds, every one of them traceable. Find what your lab is working on.</p>
          <button className="btn btn-primary" onClick={() => go('catalog')}>Browse catalog →</button>
        </div>
      </section>
    );
  }
  const below = FREE_SHIPPING_THRESHOLD - cart.subtotal;
  return (
    <section style={{ padding: '48px 0 96px' }}>
      <div className="container" style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 48, alignItems: 'flex-start' }}>
        <div>
          <div className="eyebrow" style={{ marginBottom: 14 }}>YOUR CART</div>
          <h1 style={{ fontSize: 44, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '0 0 32px' }}>{cart.count} item{cart.count > 1 ? 's' : ''}</h1>
          <div className="cart-page-list">
            {cart.lines.map(line => (
              <CartLine key={line.slug} line={line} cart={cart} onOpen={(s) => go('product', s)} />
            ))}
          </div>
        </div>
        <aside className="cart-summary">
          <div className="cart-summary-title">Order summary</div>
          <div className="cart-totals-row"><span>Subtotal</span><span className="cart-totals-v">{fmt2(cart.subtotal)}</span></div>
          <div className="cart-totals-row cart-totals-row-muted"><span>Shipping</span><span>Calculated at checkout</span></div>
          <div className="cart-totals-row cart-totals-row-muted"><span>Tax</span><span>Calculated at checkout</span></div>
          {below > 0 ? (
            <div className="cart-ship-badge">Add <strong>{fmt(below)}</strong> for free standard shipping</div>
          ) : (
            <div className="cart-ship-badge cart-ship-badge-won">✓ Free standard shipping unlocked</div>
          )}
          <button className="btn btn-primary cart-checkout-btn" onClick={() => go('checkout')}>Proceed to checkout →</button>
          <button className="btn-link cart-view-cart" onClick={() => go('catalog')}>Continue shopping</button>
          <div className="cart-summary-reassurance">
            <div className="cart-rea-item"><span>→</span><div><strong>Fast dispatch</strong><br/>Ships within 1 business day, tracked end-to-end.</div></div>
            <div className="cart-rea-item"><span>✓</span><div><strong>COA with every vial</strong><br/>Lot-specific certificate, independently assayed.</div></div>
            <div className="cart-rea-item"><span>⟲</span><div><strong>Institutional billing</strong><br/>Charged as CLARION PEP RES. Lab-friendly receipts.</div></div>
          </div>
        </aside>
      </div>
    </section>
  );
}

/* =========================================================
   Checkout Page — shipping → payment → review → submit
   ========================================================= */
function CheckoutPage({ go }) {
  const cart = useCart();
  const [step, setStep] = useShopState(1);
  const [ship, setShip] = useShopState(() => ({
    email: '', firstName: '', lastName: '', institution: '',
    address1: '', address2: '', city: '', state: '', zip: '', country: 'United States',
    phone: '',
  }));
  const [shipOption, setShipOption] = useShopState('express');
  const [pay, setPay] = useShopState({ cardName: '', cardNumber: '', expiry: '', cvc: '' });

  if (cart.count === 0) {
    return (
      <section style={{ padding: '96px 0' }}>
        <div className="container-narrow" style={{ textAlign: 'center' }}>
          <h1 style={{ fontSize: 36, fontWeight: 900, color: 'var(--fg-brand)', margin: '0 0 16px' }}>Nothing to check out</h1>
          <p style={{ color: 'var(--fg2)', marginBottom: 24 }}>Your cart is empty.</p>
          <button className="btn btn-primary" onClick={() => go('catalog')}>Browse catalog →</button>
        </div>
      </section>
    );
  }

  const shipOpt = SHIPPING.find(s => s.id === shipOption);
  const shippingCost = (shipOption === 'standard' && cart.subtotal >= FREE_SHIPPING_THRESHOLD) ? 0 : shipOpt.price;
  const tax = Math.round(cart.subtotal * 0.0875 * 100) / 100; // 8.75%
  const total = cart.subtotal + shippingCost + tax;

  const placeOrder = () => {
    const orderNum = 'CP' + Math.floor(100000 + Math.random() * 900000);
    const order = {
      orderNum,
      date: new Date().toISOString(),
      lines: cart.lines.map(l => ({ code: l.product.code, slug: l.product.slug, category: l.product.category, weight: l.product.weight, price: l.product.price, qty: l.qty, lineTotal: l.lineTotal })),
      subtotal: cart.subtotal,
      shipping: { option: shipOpt, cost: shippingCost },
      tax, total,
      ship,
      payLast4: (pay.cardNumber || '').replace(/\s+/g, '').slice(-4) || '4242',
      tracking: 'CLR-' + Math.random().toString(36).slice(2, 10).toUpperCase(),
    };
    localStorage.setItem(ORDER_KEY, JSON.stringify(order));
    // push to account orders list
    try {
      const u = JSON.parse(localStorage.getItem('clarion_user') || 'null');
      if (u) {
        const orders = JSON.parse(localStorage.getItem('clarion_orders_' + u.email) || '[]');
        orders.unshift(order);
        localStorage.setItem('clarion_orders_' + u.email, JSON.stringify(orders));
      }
    } catch {}
    cart.clear();
    decrementStock(order.lines);
    go('confirmation');
  };

  return (
    <section style={{ padding: '40px 0 96px' }}>
      <div className="container" style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 48, alignItems: 'flex-start' }}>
        <div>
          <button className="btn-link" onClick={() => go('cart')}>← Back to cart</button>
          <h1 style={{ fontSize: 40, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '16px 0 32px' }}>Checkout</h1>

          {/* Step indicator */}
          <div className="checkout-steps">
            {['Shipping', 'Payment', 'Review'].map((l, i) => {
              const n = i + 1;
              const state = n < step ? 'done' : n === step ? 'active' : 'pending';
              return (
                <div key={l} className={"checkout-step checkout-step-" + state}>
                  <div className="checkout-step-num">{state === 'done' ? '✓' : n}</div>
                  <div className="checkout-step-label">{l}</div>
                </div>
              );
            })}
          </div>

          {step === 1 && <CheckoutShipping ship={ship} setShip={setShip} shipOption={shipOption} setShipOption={setShipOption} subtotal={cart.subtotal} onNext={() => setStep(2)} />}
          {step === 2 && <CheckoutPayment pay={pay} setPay={setPay} onBack={() => setStep(1)} onNext={() => setStep(3)} />}
          {step === 3 && <CheckoutReview ship={ship} shipOpt={shipOpt} shippingCost={shippingCost} pay={pay} lines={cart.lines} subtotal={cart.subtotal} tax={tax} total={total} onBack={() => setStep(2)} onPlace={placeOrder} />}
        </div>

        <aside className="cart-summary cart-summary-sticky">
          <div className="cart-summary-title">Order summary</div>
          <div className="checkout-mini-lines">
            {cart.lines.map(l => (
              <div key={l.slug} className="checkout-mini-line">
                <div className="checkout-mini-photo"><img src="./assets/vial-photo.webp" alt="" /><span className="checkout-mini-qty">{l.qty}</span></div>
                <div className="checkout-mini-info">
                  <div className="checkout-mini-name">{l.product.code}</div>
                  <div className="checkout-mini-specs">{l.product.weight} · {l.product.purity}</div>
                </div>
                <div className="checkout-mini-price">{fmt2(l.lineTotal)}</div>
              </div>
            ))}
          </div>
          <div className="cart-totals-row"><span>Subtotal</span><span className="cart-totals-v">{fmt2(cart.subtotal)}</span></div>
          <div className="cart-totals-row"><span>Shipping ({shipOpt.label})</span><span className="cart-totals-v">{shippingCost === 0 ? 'Free' : fmt2(shippingCost)}</span></div>
          <div className="cart-totals-row"><span>Tax (est.)</span><span className="cart-totals-v">{fmt2(tax)}</span></div>
          <div className="cart-totals-row cart-totals-grand"><span>Total</span><span>{fmt2(total)}</span></div>
        </aside>
      </div>
    </section>
  );
}

function CheckoutField({ label, children, full }) {
  return (
    <label style={{ display: 'block', gridColumn: full ? '1/-1' : 'auto' }}>
      <div className="checkout-field-label">{label}</div>
      {children}
    </label>
  );
}
const checkoutInput = { width: '100%', padding: '11px 14px', border: '1px solid var(--border-strong)', borderRadius: 8, fontSize: 14, fontFamily: 'var(--font-sans)', color: 'var(--fg-brand)', background: '#fff' };

function CheckoutShipping({ ship, setShip, shipOption, setShipOption, subtotal, onNext }) {
  const upd = (k, v) => setShip(s => ({ ...s, [k]: v }));
  return (
    <form onSubmit={e => { e.preventDefault(); onNext(); }}>
      <div className="checkout-section-title">Contact</div>
      <div className="checkout-grid">
        <CheckoutField label="EMAIL" full><input type="email" style={checkoutInput} required value={ship.email} onChange={e => upd('email', e.target.value)} placeholder="you@institution.edu" /></CheckoutField>
      </div>

      <div className="checkout-section-title">Shipping address</div>
      <div className="checkout-grid">
        <CheckoutField label="FIRST NAME"><input style={checkoutInput} required value={ship.firstName} onChange={e => upd('firstName', e.target.value)} /></CheckoutField>
        <CheckoutField label="LAST NAME"><input style={checkoutInput} required value={ship.lastName} onChange={e => upd('lastName', e.target.value)} /></CheckoutField>
        <CheckoutField label="INSTITUTION (OPTIONAL)" full><input style={checkoutInput} value={ship.institution} onChange={e => upd('institution', e.target.value)} placeholder="Laboratory or research facility" /></CheckoutField>
        <CheckoutField label="ADDRESS" full><input style={checkoutInput} required value={ship.address1} onChange={e => upd('address1', e.target.value)} placeholder="Street address" /></CheckoutField>
        <CheckoutField label="APT, SUITE, BLDG (OPTIONAL)" full><input style={checkoutInput} value={ship.address2} onChange={e => upd('address2', e.target.value)} /></CheckoutField>
        <CheckoutField label="CITY"><input style={checkoutInput} required value={ship.city} onChange={e => upd('city', e.target.value)} /></CheckoutField>
        <CheckoutField label="STATE / REGION"><input style={checkoutInput} required value={ship.state} onChange={e => upd('state', e.target.value)} /></CheckoutField>
        <CheckoutField label="ZIP / POSTAL"><input style={checkoutInput} required value={ship.zip} onChange={e => upd('zip', e.target.value)} /></CheckoutField>
        <CheckoutField label="PHONE"><input type="tel" style={checkoutInput} required value={ship.phone} onChange={e => upd('phone', e.target.value)} placeholder="For delivery updates" /></CheckoutField>
      </div>

      <div className="checkout-section-title">Shipping method</div>
      <div className="checkout-ship-options">
        {SHIPPING.map(opt => {
          const isStandardFree = opt.id === 'standard' && subtotal >= FREE_SHIPPING_THRESHOLD;
          const selected = shipOption === opt.id;
          return (
            <label key={opt.id} className={"checkout-ship-opt" + (selected ? ' is-selected' : '')}>
              <input type="radio" name="ship" checked={selected} onChange={() => setShipOption(opt.id)} />
              <div className="checkout-ship-opt-body">
                <div className="checkout-ship-opt-top">
                  <div>
                    <div className="checkout-ship-opt-label">{opt.label}</div>
                    <div className="checkout-ship-opt-eta">{opt.eta}</div>
                  </div>
                  <div className="checkout-ship-opt-price">{isStandardFree ? 'Free' : fmt2(opt.price)}</div>
                </div>
                <div className="checkout-ship-opt-note">{opt.note}</div>
              </div>
            </label>
          );
        })}
      </div>

      <div style={{ marginTop: 32, display: 'flex', justifyContent: 'flex-end' }}>
        <button type="submit" className="btn btn-primary">Continue to payment →</button>
      </div>
    </form>
  );
}

function CheckoutPayment({ pay, setPay, onBack, onNext }) {
  const upd = (k, v) => setPay(p => ({ ...p, [k]: v }));
  const formatCard = (v) => v.replace(/\D/g, '').slice(0, 16).replace(/(.{4})/g, '$1 ').trim();
  const formatExp = (v) => { const d = v.replace(/\D/g, '').slice(0, 4); return d.length > 2 ? d.slice(0,2) + '/' + d.slice(2) : d; };
  return (
    <form onSubmit={e => { e.preventDefault(); onNext(); }}>
      <div className="checkout-section-title">Payment</div>
      <div style={{ background: 'var(--clarion-frost)', border: '1px solid var(--border-strong)', borderRadius: 10, padding: 14, fontSize: 12, color: 'var(--fg2)', lineHeight: 1.5, marginBottom: 24, display: 'flex', gap: 10, alignItems: 'center' }}>
        <span style={{ fontSize: 18 }}>🔒</span>
        <div>Billing descriptor will read <strong style={{ color: 'var(--fg-brand)' }}>CLARION PEP RES</strong>. Your card information is encrypted end-to-end.</div>
      </div>
      <div className="checkout-grid">
        <CheckoutField label="NAME ON CARD" full><input style={checkoutInput} required value={pay.cardName} onChange={e => upd('cardName', e.target.value)} /></CheckoutField>
        <CheckoutField label="CARD NUMBER" full><input style={checkoutInput} required value={pay.cardNumber} onChange={e => upd('cardNumber', formatCard(e.target.value))} placeholder="4242 4242 4242 4242" inputMode="numeric" /></CheckoutField>
        <CheckoutField label="EXPIRY"><input style={checkoutInput} required value={pay.expiry} onChange={e => upd('expiry', formatExp(e.target.value))} placeholder="MM/YY" inputMode="numeric" /></CheckoutField>
        <CheckoutField label="CVC"><input style={checkoutInput} required value={pay.cvc} onChange={e => upd('cvc', e.target.value.replace(/\D/g, '').slice(0,4))} placeholder="123" inputMode="numeric" /></CheckoutField>
      </div>
      <div className="checkout-section-title">Billing address</div>
      <label style={{ display: 'flex', gap: 10, alignItems: 'center', padding: 14, background: '#fff', border: '1px solid var(--border-strong)', borderRadius: 8 }}>
        <input type="checkbox" defaultChecked />
        <span style={{ fontSize: 14, color: 'var(--fg1)' }}>Same as shipping address</span>
      </label>
      <div style={{ marginTop: 32, display: 'flex', justifyContent: 'space-between' }}>
        <button type="button" className="btn btn-ghost" onClick={onBack}>← Back</button>
        <button type="submit" className="btn btn-primary">Review order →</button>
      </div>
    </form>
  );
}

function CheckoutReview({ ship, shipOpt, shippingCost, pay, lines, subtotal, tax, total, onBack, onPlace }) {
  const [attested, setAttested] = useShopState(false);
  const last4 = (pay.cardNumber || '').replace(/\s+/g, '').slice(-4) || '••••';
  return (
    <div>
      <div className="checkout-section-title">Review</div>
      <div className="checkout-review-grid">
        <div className="checkout-review-card">
          <div className="checkout-review-head"><span className="eyebrow">SHIP TO</span><button className="btn-link" onClick={onBack}>Edit</button></div>
          <div className="checkout-review-body">
            <strong>{ship.firstName} {ship.lastName}</strong>{ship.institution ? ' · ' + ship.institution : ''}<br/>
            {ship.address1}{ship.address2 ? ', ' + ship.address2 : ''}<br/>
            {ship.city}, {ship.state} {ship.zip}<br/>
            {ship.country} · {ship.phone}<br/>
            <span style={{ color: 'var(--fg2)' }}>{ship.email}</span>
          </div>
        </div>
        <div className="checkout-review-card">
          <div className="checkout-review-head"><span className="eyebrow">SHIP METHOD</span></div>
          <div className="checkout-review-body">
            <strong>{shipOpt.label}</strong> · {shippingCost === 0 ? 'Free' : fmt2(shippingCost)}<br/>
            <span style={{ color: 'var(--fg2)' }}>{shipOpt.eta}</span>
          </div>
        </div>
        <div className="checkout-review-card">
          <div className="checkout-review-head"><span className="eyebrow">PAYMENT</span><button className="btn-link" onClick={onBack}>Edit</button></div>
          <div className="checkout-review-body">
            <strong>{pay.cardName}</strong><br/>
            Card ending in <span style={{ fontFamily: 'var(--font-mono)' }}>{last4}</span> · Exp {pay.expiry || '••/••'}
          </div>
        </div>
      </div>

      <label className="checkout-attest">
        <input type="checkbox" checked={attested} onChange={e => setAttested(e.target.checked)} />
        <span>I confirm I am a qualified researcher and these compounds will be used <strong>for research purposes only</strong>, never for human or veterinary consumption.</span>
      </label>

      <div style={{ marginTop: 24, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <button type="button" className="btn btn-ghost" onClick={onBack}>← Back</button>
        <button className="btn btn-primary" disabled={!attested} onClick={onPlace} style={{ opacity: attested ? 1 : .4, pointerEvents: attested ? 'auto' : 'none' }}>
          Place order · {fmt2(total)}
        </button>
      </div>
    </div>
  );
}

/* =========================================================
   Order Confirmation
   ========================================================= */
function OrderConfirmationPage({ go }) {
  let order;
  try { order = JSON.parse(localStorage.getItem(ORDER_KEY) || 'null'); } catch { order = null; }
  if (!order) {
    return (
      <section style={{ padding: '96px 0' }}>
        <div className="container-narrow" style={{ textAlign: 'center' }}>
          <h1 style={{ fontSize: 36, fontWeight: 900, color: 'var(--fg-brand)' }}>No recent order</h1>
          <p style={{ color: 'var(--fg2)', marginBottom: 24 }}>We don't have a recent order to show.</p>
          <button className="btn btn-primary" onClick={() => go('catalog')}>Browse catalog →</button>
        </div>
      </section>
    );
  }
  const dt = new Date(order.date);
  const dateStr = dt.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
  const etaFrom = new Date(dt.getTime() + 1 * 24 * 60 * 60 * 1000);
  const etaTo   = new Date(dt.getTime() + 5 * 24 * 60 * 60 * 1000);
  const etaStr = `${etaFrom.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })} – ${etaTo.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`;

  return (
    <>
      <section style={{ padding: '72px 0 40px', background: 'linear-gradient(180deg, var(--clarion-frost) 0%, #fff 100%)' }}>
        <div className="container-narrow">
          <div className="confirm-check">
            <svg width="28" height="28" viewBox="0 0 28 28" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
              <path d="M6 14l5 5 11-12" />
            </svg>
          </div>
          <div className="eyebrow eyebrow-teal" style={{ marginBottom: 14 }}>ORDER CONFIRMED · {dateStr.toUpperCase()}</div>
          <h1 style={{ fontSize: 48, fontWeight: 900, color: 'var(--fg-brand)', letterSpacing: '-0.02em', margin: '0 0 16px', lineHeight: 1.05 }}>
            Thank you, {order.ship.firstName || 'researcher'}.<br/>
            <span style={{ fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontWeight: 400, color: 'var(--clarion-teal)' }}>Your order is in hand.</span>
          </h1>
          <p style={{ fontSize: 16, color: 'var(--fg1)', lineHeight: 1.65, maxWidth: 620, margin: 0 }}>
            Order <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 15 }}>{order.orderNum}</strong> has been received. A confirmation receipt has been sent to <strong>{order.ship.email}</strong>. COAs for every lot in your order will arrive with the shipment and by email 24 hours before dispatch.
          </p>
        </div>
      </section>

      <section style={{ padding: '0 0 96px' }}>
        <div className="container-narrow">
          <div className="confirm-track">
            <div className="confirm-track-row">
              <div>
                <div className="confirm-track-label">TRACKING NUMBER</div>
                <div className="confirm-track-value">{order.tracking}</div>
              </div>
              <div>
                <div className="confirm-track-label">ESTIMATED DELIVERY</div>
                <div className="confirm-track-value">{etaStr}</div>
              </div>
              <div>
                <div className="confirm-track-label">SHIP METHOD</div>
                <div className="confirm-track-value">{order.shipping.option.label}</div>
              </div>
            </div>
            <div className="confirm-track-bar">
              {['Ordered', 'Preparing', 'Dispatched', 'In transit', 'Delivered'].map((s, i) => (
                <div key={s} className={"confirm-track-step" + (i === 0 ? ' is-active' : i === 0 ? ' is-done' : '')}>
                  <div className="confirm-track-dot" />
                  <div className="confirm-track-step-label">{s}</div>
                </div>
              ))}
            </div>
          </div>

          <div className="confirm-grid">
            <div>
              <div className="eyebrow" style={{ marginBottom: 14 }}>ITEMS</div>
              <div className="confirm-lines">
                {order.lines.map(l => (
                  <div key={l.slug} className="confirm-line">
                    <div className="confirm-line-photo"><img src="./assets/vial-photo.webp" alt="" /></div>
                    <div className="confirm-line-info">
                      <div className="cart-line-cat">{l.category}</div>
                      <div className="confirm-line-name">{l.code}</div>
                      <div className="cart-line-specs">{l.weight} · Qty {l.qty}</div>
                    </div>
                    <div className="cart-line-price">
                      <div className="cart-line-linetotal">{fmt2(l.lineTotal)}</div>
                      {l.qty > 1 && <div className="cart-line-each">{fmt(l.price)} each</div>}
                    </div>
                  </div>
                ))}
              </div>
            </div>

            <aside className="confirm-summary">
              <div className="cart-summary-title">Receipt</div>
              <div className="cart-totals-row"><span>Subtotal</span><span className="cart-totals-v">{fmt2(order.subtotal)}</span></div>
              <div className="cart-totals-row"><span>Shipping</span><span className="cart-totals-v">{order.shipping.cost === 0 ? 'Free' : fmt2(order.shipping.cost)}</span></div>
              <div className="cart-totals-row"><span>Tax</span><span className="cart-totals-v">{fmt2(order.tax)}</span></div>
              <div className="cart-totals-row cart-totals-grand"><span>Total</span><span>{fmt2(order.total)}</span></div>
              <div style={{ fontSize: 12, color: 'var(--fg2)', marginTop: 12, fontFamily: 'var(--font-mono)', letterSpacing: '.04em' }}>
                CHARGED TO CARD ENDING {order.payLast4}
              </div>
            </aside>
          </div>

          <div className="confirm-next">
            <h3 style={{ margin: '0 0 14px', fontSize: 20, fontWeight: 800, color: 'var(--fg-brand)' }}>What happens next</h3>
            <div className="confirm-next-steps">
              <div>
                <div className="confirm-next-num">01</div>
                <strong>COA emailed</strong>
                <p>Lot-specific certificates for each SKU arrive in your inbox within 24 hours.</p>
              </div>
              <div>
                <div className="confirm-next-num">02</div>
                <strong>Packed & shipped</strong>
                <p>Your order ships in a standard container with tamper-evident seal.</p>
              </div>
              <div>
                <div className="confirm-next-num">03</div>
                <strong>Signature delivery</strong>
                <p>A signature is required on arrival. Transfer to lab freezer immediately upon receipt.</p>
              </div>
            </div>
          </div>

          <div style={{ display: 'flex', gap: 12, marginTop: 40 }}>
            <button className="btn btn-ghost" onClick={() => go('account')}>View in account</button>
            <button className="btn btn-primary" onClick={() => go('catalog')}>Continue shopping →</button>
          </div>
        </div>
      </section>
    </>
  );
}

Object.assign(window, {
  useCart, fmt, fmt2, CART_KEY, ORDER_KEY,
  trackRecentlyViewed, getRecentlyViewed, viewersFor,
  CartDrawer, CartOverlay, CartLine,
  CartPage, CheckoutPage, OrderConfirmationPage,
});
