// screens-flow.jsx — Home, Scan, Cluster browse + Product sheet

// ─────────────────────────────────────────────────────────────
// HOME SCREEN
// ─────────────────────────────────────────────────────────────
const ScreenHome = ({ user, onScan, onOpenProfile, onOpenVouchers, onOpenRiwayat, onOpenProduct, onOpenCari, onOpenMap, navbar }) => {
  const isGuest = !user;
  const recentTx = MOCK_RECENT_TX.slice(0, 2);
  const popular = MOCK_POPULAR_IDS.map(id => MOCK_PRODUCTS.find(p => p.id === id)).filter(Boolean);

  return (
    <div className="app">
      <div className="app-scroll">
        {/* ─── HEADER (navy band) ─────────────────────────── */}
        <div style={{
          background: 'linear-gradient(180deg, var(--eb-navy) 0%, var(--eb-navy) 90%, var(--eb-bg) 100%)',
          padding: '60px 16px 0',
          position: 'relative',
          overflow: 'hidden',
        }}>
          {/* subtle bee dot grid */}
          <div style={{
            position: 'absolute', inset: 0,
            backgroundImage: 'radial-gradient(circle, rgba(var(--eb-amber-rgb), 0.10) 1px, transparent 1px)',
            backgroundSize: '24px 24px',
            mask: 'linear-gradient(180deg, #000 0%, transparent 75%)',
            WebkitMask: 'linear-gradient(180deg, #000 0%, transparent 75%)',
            pointerEvents: 'none',
          }} />

          {/* logo + actions */}
          <div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <EbLogo size={32} withText light />
            <div style={{ display: 'flex', gap: 8 }}>
              {!isGuest && (
                <button className="icon-btn" onClick={onOpenVouchers} style={{
                  background: 'rgba(255,255,255,0.10)', borderColor: 'rgba(255,255,255,0.18)', color: '#fff',
                  position: 'relative',
                }}>
                  <Icon name="ticket" size={18} />
                  {user.vouchers.length > 0 && (
                    <span style={{
                      position: 'absolute', top: 3, right: 3,
                      minWidth: 14, height: 14, borderRadius: 7, padding: '0 4px',
                      background: 'var(--eb-amber)', color: 'var(--eb-navy)',
                      fontSize: 9, fontWeight: 700, fontFamily: 'IBM Plex Mono',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      border: '1.5px solid var(--eb-navy)',
                    }}>{user.vouchers.length}</span>
                  )}
                </button>
              )}
              <button className="icon-btn" onClick={onOpenProfile} style={{
                background: 'rgba(255,255,255,0.10)', borderColor: 'rgba(255,255,255,0.18)', color: '#fff',
              }}>
                <Icon name="user" size={18} />
              </button>
            </div>
          </div>

          {/* greeting */}
          <div style={{ position: 'relative', marginTop: 22, marginBottom: 18, color: '#fff' }}>
            {(() => {
              const b = window.BRAND || {};
              const g = b.greeting || {};
              if (isGuest) {
                return (
                  <>
                    <div style={{ fontSize: 13, opacity: 0.65, letterSpacing: '0.02em' }}>
                      {g.guestPre || 'Selamat datang di'}
                    </div>
                    <div style={{ fontSize: 26, fontWeight: 700, marginTop: 2, letterSpacing: '-0.02em', lineHeight: 1.15, whiteSpace: 'pre-line' }}>
                      {g.guestTitle || 'Warung 24 jam\ndi sebelah kamu'}
                    </div>
                  </>
                );
              }
              return (
                <>
                  <div style={{ fontSize: 13, opacity: 0.65, letterSpacing: '0.02em' }}>
                    {g.loggedInPre || 'Halo,'} {user.name.split(' ')[0]} 👋
                  </div>
                  <div style={{ fontSize: 22, fontWeight: 700, marginTop: 2, letterSpacing: '-0.02em', lineHeight: 1.15, whiteSpace: 'pre-line' }}>
                    {g.loggedInTitle || 'Mau ambil apa\nmalam ini?'}
                  </div>
                </>
              );
            })()}
          </div>

          {/* HERO SCAN CARD */}
          <button onClick={onScan} className="hero-scan">
            {/* animated scan corners */}
            <span className="hero-scan-corner tl" />
            <span className="hero-scan-corner tr" />
            <span className="hero-scan-corner bl" />
            <span className="hero-scan-corner br" />
            <span className="hero-scan-line" />

            <div className="hero-scan-icon">
              <Icon name="qr" size={32} stroke={2} />
            </div>
            <div className="hero-scan-body">
              <div className="hero-scan-title">Pindai QR di kotak</div>
              <div className="hero-scan-sub">Sentuhkan kamera ke stiker QR · langsung belanja</div>
            </div>
            <div className="hero-scan-cta">
              <Icon name="arrow-right" size={18} stroke={2.5} />
            </div>
          </button>
          <div style={{ height: 18 }} />
        </div>

        {/* ─── PROMO BANNER ───────────────────────────────── */}
        <div style={{ padding: '14px 0 0' }}>
          <PromoBanner promos={MOCK_PROMOS} />
        </div>

        {/* ─── CARI BAR (jumps to Cari screen) ──────────────── */}
        <div style={{ padding: '14px 16px 0' }}>
          <button className="home-search" onClick={onOpenCari}>
            <Icon name="search" size={18} color="var(--eb-faint)" />
            <span className="home-search-text">{(window.BRAND && window.BRAND.searchPlaceholder) || 'Cari Panadol, Indomie, Kapal Api…'}</span>
            <Icon name="arrow-right" size={14} color="var(--eb-faint)" />
          </button>
        </div>

        {/* ─── PRODUK POPULER ─────────────────────────────── */}
        <div className="section">
          <span className="section-title">Produk populer</span>
          <button className="section-action" onClick={onOpenCari} style={{ background: 'transparent', border: 0 }}>
            Lihat semua
          </button>
        </div>
        <div className="hscroll">
          {popular.map(p => (
            <button key={p.id} className="popular-card" onClick={() => onOpenProduct && onOpenProduct(p)}>
              <ProductThumb product={p} />
              <div className="popular-card-body">
                <div className="popular-card-name">{p.name}</div>
                <div className="popular-card-meta">{p.unit}</div>
                <span className="price popular-card-price">{fmtRp(p.price)}</span>
              </div>
            </button>
          ))}
        </div>

        {/* ─── PETA MESIN ─────────────────────────────────── */}
        <div style={{ padding: '18px 16px 4px' }}>
          <button onClick={onOpenMap} className="card" style={{
            width: '100%', padding: 14,
            display: 'flex', alignItems: 'center', gap: 12,
            textAlign: 'left',
            background: 'linear-gradient(135deg, var(--eb-navy) 0%, var(--eb-navy-700) 100%)',
            border: 'none', color: '#fff',
            position: 'relative', overflow: 'hidden',
          }}>
            <div style={{
              position: 'absolute', inset: 0, opacity: 0.18,
              backgroundImage: 'radial-gradient(circle, var(--eb-amber) 1px, transparent 1px)',
              backgroundSize: '20px 20px',
              mask: 'linear-gradient(135deg, #000 0%, transparent 70%)',
              WebkitMask: 'linear-gradient(135deg, #000 0%, transparent 70%)',
              pointerEvents: 'none',
            }} />
            <div style={{
              position: 'relative',
              width: 48, height: 48, borderRadius: 12,
              background: 'rgba(var(--eb-amber-rgb), 0.22)', color: 'var(--eb-amber)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
            }}>
              <Icon name="pin" size={22} />
            </div>
            <div style={{ flex: 1, minWidth: 0, position: 'relative' }}>
              <div style={{ fontSize: 15, fontWeight: 700, color: '#fff', letterSpacing: '-0.01em' }}>
                Peta mesin {(window.BRAND && window.BRAND.name) || 'Elektrobee'}
              </div>
              <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.75)', marginTop: 3, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                <span><b style={{ color: '#fff', fontFamily: 'IBM Plex Mono', fontWeight: 700 }}>{MOCK_MACHINES.length}</b> mesin di Jakarta</span>
              </div>
            </div>
            <Icon name="chevron" size={18} color="rgba(255,255,255,0.6)" />
          </button>
        </div>

        {/* ─── LOGGED-IN ONLY: VOUCHER + RIWAYAT ──────────── */}
        {!isGuest && user.vouchers.length > 0 && (
          <>
            <div className="section">
              <span className="section-title">Voucher aktif</span>
              <button className="section-action" onClick={onOpenVouchers} style={{ background: 'transparent', border: 0 }}>
                {user.vouchers.length} aktif
              </button>
            </div>
            <div style={{ padding: '0 16px 4px' }}>
              <button onClick={onOpenVouchers} className="voucher-card" style={{ width: '100%', textAlign: 'left' }}>
                <div className="voucher-icon">
                  <Icon name="ticket" size={26} />
                </div>
                <div style={{ flex: 1, paddingLeft: 12 }}>
                  <div className="price" style={{ fontSize: 18, color: 'var(--eb-navy)' }}>
                    {fmtRp(user.vouchers.reduce((s,v) => s+v.amount, 0))}
                  </div>
                  <div style={{ fontSize: 11, color: 'var(--eb-navy)', opacity: 0.75, marginTop: 2 }}>
                    {user.vouchers[0].reason}
                  </div>
                  <div style={{ fontSize: 10, color: 'var(--eb-navy)', opacity: 0.55, marginTop: 4 }}>
                    Berlaku s/d {user.vouchers[0].expires}
                  </div>
                </div>
              </button>
            </div>
          </>
        )}

        {!isGuest && (
          <>
            <div className="section">
              <span className="section-title">Transaksi terakhir</span>
              <button className="section-action" onClick={onOpenRiwayat} style={{ background: 'transparent', border: 0 }}>
                Lihat semua
              </button>
            </div>
            <div className="list" style={{ margin: '0 16px 4px', borderRadius: 14, overflow: 'hidden', border: '1px solid var(--eb-line-soft)' }}>
              {recentTx.map(tx => (
                <button key={tx.id} className="list-row" onClick={onOpenRiwayat} style={{
                  width: '100%', textAlign: 'left',
                }}>
                  <div style={{
                    width: 36, height: 36, borderRadius: 10, flexShrink: 0,
                    background: tx.status === 'partial' ? 'var(--eb-warn-soft)' : 'var(--eb-success-soft)',
                    color: tx.status === 'partial' ? 'var(--eb-warn)' : 'var(--eb-success)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>
                    <Icon name={tx.status === 'partial' ? 'info' : 'check'} size={16} stroke={2.5} />
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--eb-ink)',
                      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{tx.items}</div>
                    <div style={{ fontSize: 11, color: 'var(--eb-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {tx.at} · {tx.cluster}
                    </div>
                  </div>
                  <span className="price" style={{ fontSize: 13, flexShrink: 0 }}>{fmtRp(tx.total)}</span>
                </button>
              ))}
            </div>
          </>
        )}

        {/* ─── GUEST ONLY: CARA PAKAI + DAFTAR ─────────────── */}
        {isGuest && (
          <>
            <div className="section">
              <span className="section-title">Cara pakai</span>
            </div>
            <div className="how-row" style={{ padding: '0 16px' }}>
              {((window.BRAND && window.BRAND.howSteps) || [
                { n: 1, t: 'Pindai QR',    d: 'di kotak mesin', icon: 'qr' },
                { n: 2, t: 'Pilih & bayar', d: 'QRIS otomatis',  icon: 'card' },
                { n: 3, t: 'Ambil barang',  d: 'dari kotak menyala', icon: 'package' },
              ]).map(s => (
                <div key={s.n} className="how-step">
                  <div className="how-step-icon">
                    <Icon name={s.icon} size={18} />
                  </div>
                  <div className="how-step-text">
                    <div className="how-step-title">{s.t}</div>
                    <div className="how-step-desc">{s.d}</div>
                  </div>
                </div>
              ))}
            </div>

            <div style={{ padding: '16px 16px 4px' }}>
              <button onClick={onOpenProfile} className="card" style={{
                width: '100%', padding: 14, border: 'none',
                background: 'linear-gradient(135deg, #FDF1D6 0%, #FFE3A8 100%)',
                display: 'flex', gap: 12, alignItems: 'center', textAlign: 'left',
              }}>
                <div style={{
                  width: 44, height: 44, borderRadius: 12,
                  background: 'var(--eb-navy)', color: 'var(--eb-amber)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                }}>
                  <Icon name="sparkle" size={22} />
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 14, color: 'var(--eb-navy)' }}>Daftar = diskon</div>
                  <div style={{ fontSize: 11, color: 'var(--eb-navy)', opacity: 0.75, lineHeight: 1.35, marginTop: 2 }}>
                    Voucher Rp 10.000 untuk transaksi pertama
                  </div>
                </div>
                <Icon name="chevron" size={18} color="var(--eb-navy)" />
              </button>
            </div>
          </>
        )}

        <div style={{ height: 30 }} />
      </div>
      {navbar}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// PROMO BANNER — swipeable horizontal carousel with dots
// ─────────────────────────────────────────────────────────────
const PromoBanner = ({ promos }) => {
  const [i, setI] = React.useState(0);
  const scrollerRef = React.useRef(null);

  const onScroll = (e) => {
    const w = e.target.clientWidth;
    const idx = Math.round(e.target.scrollLeft / w);
    if (idx !== i) setI(idx);
  };

  return (
    <div>
      <div className="promo-scroller" ref={scrollerRef} onScroll={onScroll}>
        {promos.map((p, idx) => (
          <PromoSlide key={p.id} promo={p} />
        ))}
      </div>
      <div className="promo-dots">
        {promos.map((_, idx) => (
          <button key={idx} className="promo-dot" data-active={idx === i} onClick={() => {
            const w = scrollerRef.current.clientWidth;
            scrollerRef.current.scrollTo({ left: idx * w, behavior: 'smooth' });
          }} />
        ))}
      </div>
    </div>
  );
};

const PromoSlide = ({ promo }) => (
  <div className="promo-slide">
    <image-slot
      id={promo.slotId}
      shape="rounded"
      radius="16"
      placeholder={promo.placeholder}
      style={{ width: '100%', height: '100%', display: 'block' }}
    ></image-slot>
  </div>
);

// ─────────────────────────────────────────────────────────────
// NEARBY CARD — used in horizontal strip
// ─────────────────────────────────────────────────────────────
const NearbyCard = ({ n, locOn, onTap }) => {
  const fmtDist = (m) => m < 1000 ? `${m} m` : `${(m/1000).toFixed(1).replace('.', ',')} km`;
  return (
    <button className="nearby-card" onClick={onTap}>
      <div className="nearby-card-top">
        <div className="nearby-card-icon">
          <Icon name="pin" size={18} />
        </div>
        {n.isCurrent && locOn && (
          <span className="pill pill-amber" style={{ fontSize: 9, padding: '2px 6px' }}>
            Di sini
          </span>
        )}
        {!n.online && (
          <span className="pill pill-stock-out" style={{ fontSize: 9, padding: '2px 6px' }}>
            Offline
          </span>
        )}
      </div>
      <div className="nearby-card-name">{n.name}</div>
      <div className="nearby-card-area">{n.area}</div>
      <div className="nearby-card-foot">
        <span style={{ fontFamily: 'IBM Plex Mono', fontWeight: 600, color: 'var(--eb-navy)', fontSize: 12 }}>
          {locOn ? fmtDist(n.distance) : `${n.cubes} kotak`}
        </span>
        {locOn && (
          <span style={{ fontSize: 10, color: 'var(--eb-muted)' }}>{n.cubes} kotak</span>
        )}
      </div>
    </button>
  );
};

// ─────────────────────────────────────────────────────────────
// SCAN SCREEN — camera viewport with QR overlay
// ─────────────────────────────────────────────────────────────
const ScreenScan = ({ onBack, onDetected }) => {
  const [hint, setHint] = React.useState('Arahkan kamera ke QR di kotak');

  // Simulate auto-detect after a moment if user taps "Simulasikan"
  React.useEffect(() => {
    const t = setTimeout(() => setHint('Cari kotak yang menyala kuning — itu QR-nya'), 3500);
    return () => clearTimeout(t);
  }, []);

  return (
    <div className="app" style={{ background: '#000' }}>
      {/* fake camera feed — dark navy backdrop with subtle vignette */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'radial-gradient(circle at center, var(--eb-navy) 0%, var(--eb-navy) 75%)',
        overflow: 'hidden',
      }}>
        {/* subtle pretend "wall of cubes" hint behind the scanner */}
        <div style={{
          position: 'absolute', top: '50%', left: '50%',
          width: 320, height: 200, transform: 'translate(-50%, -50%)',
          opacity: 0.15,
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gridTemplateRows: 'repeat(2, 1fr)', gap: 4,
        }}>
          {Array.from({ length: 8 }).map((_, i) => (
            <div key={i} style={{ background: 'rgba(var(--eb-amber-rgb), 0.18)', borderRadius: 4 }} />
          ))}
        </div>
      </div>

      <div className="scan-viewport" />
      <div className="scan-frame">
        <div className="scan-corner tl" />
        <div className="scan-corner tr" />
        <div className="scan-corner bl" />
        <div className="scan-corner br" />
        <div className="scan-line" />
      </div>

      {/* Top bar */}
      <div style={{
        position: 'absolute', top: 0, left: 0, right: 0,
        padding: '52px 16px 0',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        zIndex: 10,
      }}>
        <button onClick={onBack} className="icon-btn" style={{
          background: 'rgba(0,0,0,0.4)', color: '#fff', border: '1px solid rgba(255,255,255,0.15)',
        }}>
          <Icon name="close" size={20} />
        </button>
        <div style={{
          padding: '6px 14px', borderRadius: 999,
          background: 'rgba(0,0,0,0.5)', color: '#fff',
          fontSize: 12, fontWeight: 500,
          border: '1px solid rgba(255,255,255,0.12)',
          whiteSpace: 'nowrap',
        }}>Pindai QR Kotak</div>
        <button className="icon-btn" style={{
          background: 'rgba(0,0,0,0.4)', color: '#fff', border: '1px solid rgba(255,255,255,0.15)',
        }}>
          <Icon name="flash" size={18} />
        </button>
      </div>

      {/* Bottom instruction + simulate button */}
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0,
        padding: '24px 16px 38px',
        background: 'linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.85) 60%)',
        zIndex: 10,
        display: 'flex', flexDirection: 'column', gap: 14,
      }}>
        <div style={{ color: '#fff', textAlign: 'center', fontSize: 14, fontWeight: 500, opacity: 0.9 }}>
          {hint}
        </div>
        <button onClick={() => onDetected(MOCK_MACHINES[0])} className="btn btn-primary btn-block">
          Simulasikan pindai berhasil
        </button>
        <div style={{ color: 'rgba(255,255,255,0.5)', textAlign: 'center', fontSize: 11 }}>
          Pindai QR pada mesin yang kamu pilih
        </div>
      </div>
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// MACHINE VIEW — products inside one scanned machine (max 9 SKUs)
// No search, no filter, no categories. Spinner mechanism shown as hero.
// ─────────────────────────────────────────────────────────────
const ScreenMachine = ({ machine, cart, onAddToCart, onRemoveFromCart, onBack, onOpenCart, onOpenProduct, onSwitchMachine }) => {
  const products = PRODUCTS_FOR_MACHINE(machine.id);

  const cartCount = Object.values(cart).reduce((s, v) => s + v, 0);
  const cartTotal = Object.entries(cart).reduce((s, [pid, qty]) => {
    const p = MOCK_PRODUCTS.find(x => x.id === pid);
    return s + (p?.price || 0) * qty;
  }, 0);

  const inStockCount = products.filter(p => p.stock > 0).length;

  return (
    <div className="app">
      <Topbar
        title={machine.name}
        sub={machine.location}
        onBack={onBack}
        right={
          <button className="icon-btn ghost" onClick={onOpenCart} style={{ position: 'relative' }}>
            <Icon name="cart" size={20} />
            {cartCount > 0 && (
              <span style={{
                position: 'absolute', top: 4, right: 4,
                minWidth: 16, height: 16, borderRadius: 8, padding: '0 4px',
                background: 'var(--eb-amber)', color: 'var(--eb-navy)',
                fontSize: 10, fontWeight: 700, fontFamily: 'IBM Plex Mono',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>{cartCount}</span>
            )}
          </button>
        }
      />

      <div className="app-scroll">
        {/* Machine status banner */}
        <div style={{ padding: '0 16px 12px' }}>
          <div className="machine-status">
            <div className="machine-status-icon">
              <SpinnerIcon size={36} slots={products.length} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="machine-status-title">
                <span style={{
                  width: 6, height: 6, borderRadius: 3,
                  background: 'var(--eb-success)', display: 'inline-block',
                  boxShadow: '0 0 6px var(--eb-success)',
                }} />
                Mesin aktif
              </div>
              <div className="machine-status-sub">
                {products.length} produk · {inStockCount} tersedia · spinner siap
              </div>
            </div>
          </div>
        </div>

        {/* Adult-only banner */}
        {machine.adultOnly && (
          <div style={{ padding: '0 16px 12px' }}>
            <div style={{
              padding: 12, borderRadius: 12,
              background: '#2C3447', color: '#fff',
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <Icon name="shield" size={18} color="var(--eb-amber)" />
              <div style={{ flex: 1, fontSize: 12, lineHeight: 1.4 }}>
                Mesin ini berisi <b>produk khusus 21+</b>. Pembelian memerlukan verifikasi KTP.
              </div>
            </div>
          </div>
        )}

        {/* Product grid — max 9 items, 2 columns */}
        {products.length === 0 ? (
          <div className="empty">
            <Icon name="package" size={28} color="var(--eb-faint)" />
            <div style={{ marginTop: 8, fontWeight: 600 }}>Mesin sedang kosong</div>
            <div style={{ fontSize: 12, marginTop: 4 }}>Operator sedang mengisi ulang</div>
          </div>
        ) : (
          <div className="product-grid">
            {products.map(p => (
              <ProductCard
                key={p.id}
                product={p}
                inCart={cart[p.id] || 0}
                onTap={onOpenProduct}
              />
            ))}
          </div>
        )}

        {cartCount > 0 && <div style={{ height: 86 }} />}
      </div>

      {/* Sticky cart bar */}
      {cartCount > 0 && (
        <div style={{
          position: 'absolute', left: 12, right: 12, bottom: 36,
          background: 'var(--eb-navy)', color: '#fff',
          borderRadius: 16, padding: '10px 12px 10px 14px',
          display: 'flex', alignItems: 'center', gap: 10,
          boxShadow: '0 16px 36px rgba(var(--eb-navy-rgb), 0.35)',
          zIndex: 5,
        }}>
          <div style={{
            width: 36, height: 36, borderRadius: 10,
            background: 'var(--eb-amber)', color: 'var(--eb-navy)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            position: 'relative',
          }}>
            <Icon name="cart" size={18} />
            <span style={{
              position: 'absolute', top: -4, right: -4,
              minWidth: 16, height: 16, borderRadius: 8, padding: '0 4px',
              background: '#fff', color: 'var(--eb-navy)',
              fontSize: 10, fontWeight: 700, fontFamily: 'IBM Plex Mono',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              border: '1.5px solid var(--eb-navy)',
            }}>{cartCount}</span>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 11, opacity: 0.7 }}>Keranjang · habis 2:47</div>
            <div className="price" style={{ fontSize: 16, color: '#fff' }}>{fmtRp(cartTotal)}</div>
          </div>
          <button onClick={onOpenCart} className="btn btn-primary btn-sm" style={{ height: 36, padding: '0 16px' }}>
            Lanjut
            <Icon name="arrow-right" size={14} stroke={2.5} />
          </button>
        </div>
      )}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// PRODUCT SHEET — bottom sheet with detail + add to cart
// ─────────────────────────────────────────────────────────────
const ProductSheet = ({ product, cart, onAdd, onRemove, onClose, onBuyNow, onAgeGate, user, machine }) => {
  if (!product) return null;
  const qty = cart[product.id] || 0;

  const handleAdd = () => {
    if (product.isAdult && !user?.verifiedAge) {
      onAgeGate(product);
      return;
    }
    onAdd(product);
  };

  const handleBuyNow = () => {
    if (product.isAdult && !user?.verifiedAge) {
      onAgeGate(product);
      return;
    }
    onBuyNow(product);
  };

  return (
    <BottomSheet open={!!product} onClose={onClose}>
      <div style={{ overflow: 'auto', padding: '0 0 14px' }}>
        {/* Hero */}
        <div style={{ padding: '4px 20px 18px', display: 'flex', gap: 14 }}>
          <ProductThumb product={product} size={104} />
          <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 4 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
              <span style={{ fontSize: 11, color: 'var(--eb-muted)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.04em' }}>
                {product.brand}
              </span>
              {product.isAdult && <span className="pill pill-21">21+</span>}
            </div>
            <div style={{ fontSize: 19, fontWeight: 700, lineHeight: 1.15, color: 'var(--eb-ink)', letterSpacing: '-0.02em' }}>
              {product.name}
            </div>
            <div style={{ fontSize: 13, color: 'var(--eb-muted)', marginTop: 2 }}>{product.unit}</div>
            <div style={{ marginTop: 'auto', display: 'flex', alignItems: 'baseline', gap: 8 }}>
              <span className="price" style={{ fontSize: 22, color: 'var(--eb-navy)' }}>{fmtRp(product.price)}</span>
            </div>
          </div>
        </div>

        {/* Stock + machine */}
        <div style={{ padding: '0 20px 14px', display: 'flex', flexDirection: 'column', gap: 8 }}>
          <div className="status-row">
            <span className="dot" style={{ background: product.stock > 5 ? 'var(--eb-success)' : product.stock > 0 ? 'var(--eb-warn)' : 'var(--eb-danger)' }} />
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 600 }}>
                {product.stock === 0 ? 'Habis di mesin ini' : product.stock <= 5 ? `Tinggal ${product.stock} pcs` : `Tersedia ${product.stock} pcs`}
              </div>
              <div style={{ fontSize: 11, color: 'var(--eb-muted)' }}>
                Stok diperbarui beberapa detik lalu
              </div>
            </div>
          </div>
          {machine && (
            <div className="status-row">
              <div style={{
                width: 32, height: 32, borderRadius: 7,
                background: 'var(--eb-navy)', color: '#fff',
                display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
              }}>
                <SpinnerIcon size={18} slots={PRODUCTS_FOR_MACHINE(machine.id).length} />
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>Mesin {machine.no} · {machine.name}</div>
                <div style={{ fontSize: 11, color: 'var(--eb-muted)' }}>Spinner siap dispense</div>
              </div>
            </div>
          )}
        </div>

        {/* Description */}
        <div style={{ padding: '0 20px 12px' }}>
          <div className="section-title" style={{ padding: 0, marginBottom: 6 }}>Deskripsi</div>
          <div style={{ fontSize: 13, color: 'var(--eb-ink-2)', lineHeight: 1.5, textWrap: 'pretty' }}>
            {productDescription(product)}
          </div>
        </div>

        {/* 21+ warning */}
        {product.isAdult && (
          <div style={{ padding: '0 20px 14px' }}>
            <div style={{
              padding: 12, borderRadius: 12,
              background: '#2C3447', color: '#fff',
              display: 'flex', gap: 10, alignItems: 'flex-start',
            }}>
              <Icon name="shield" size={18} color="var(--eb-amber)" />
              <div style={{ fontSize: 12, lineHeight: 1.4 }}>
                <b>Produk khusus 21+.</b> Perlu verifikasi usia (KTP) untuk membeli. Login dulu jika belum.
              </div>
            </div>
          </div>
        )}
      </div>

      {/* Sticky bottom actions */}
      <div style={{
        background: 'var(--eb-bg-elev)',
        padding: '12px 20px 22px',
        borderTop: '1px solid var(--eb-line-soft)',
        display: 'flex', gap: 10, alignItems: 'center',
      }}>
        {qty > 0 ? (
          <div style={{
            display: 'flex', alignItems: 'center',
            border: '1.5px solid var(--eb-navy)', borderRadius: 12,
            height: 48, padding: '0 4px',
          }}>
            <button onClick={() => onRemove(product)} style={{
              width: 36, height: 40, color: 'var(--eb-navy)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <Icon name="minus" size={18} stroke={2.5} />
            </button>
            <div style={{ minWidth: 22, textAlign: 'center', fontWeight: 700, fontFamily: 'IBM Plex Mono', color: 'var(--eb-navy)' }}>{qty}</div>
            <button onClick={handleAdd} style={{
              width: 36, height: 40, color: 'var(--eb-navy)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }} disabled={qty >= product.stock}>
              <Icon name="plus" size={18} stroke={2.5} />
            </button>
          </div>
        ) : (
          <button className="btn btn-ghost" onClick={handleAdd} disabled={product.stock === 0}
            style={{ flex: 1 }}>
            <Icon name="cart" size={18} />
            Tambah
          </button>
        )}
        <button className="btn btn-primary" onClick={handleBuyNow}
          disabled={product.stock === 0}
          style={{ flex: 1.4 }}>
          {product.stock === 0 ? 'Habis' : 'Beli langsung'}
        </button>
      </div>
    </BottomSheet>
  );
};

// Short rule-based product blurb
function productDescription(p) {
  const c = p.category;
  const tail = p.isAdult
    ? 'Dijual eceran khusus dewasa.'
    : 'Dijual satuan — beli sebatas yang kamu butuhkan.';
  if (c === 'obat')      return `${p.name} dijual 1 strip / 1 sachet. ${tail}`;
  if (c === 'kopi')      return `Sachet siap seduh. ${tail}`;
  if (c === 'makanan')   return `Mi instan / makanan ringan, ambil satuan. ${tail}`;
  if (c === 'snack')     return `Snack porsi sekali makan. ${tail}`;
  if (c === 'perawatan') return `Saset sekali pakai — pas untuk traveling atau coba dulu. ${tail}`;
  if (c === 'dewasa')    return `Produk eceran khusus 21+. ${tail}`;
  return `Tersedia eceran di mesin ini. ${tail}`;
}

Object.assign(window, { ScreenHome, ScreenScan, ScreenMachine, ProductSheet, PromoBanner, PromoSlide, NearbyCard });
