/* ============================================================
   basket.fun — App shell + Explore screen
   ============================================================ */

/* ---------------- App shell (sidebar + topbar) ---------------- */
function NavItem({ icon, label, active, onClick, badge }) {
  const [h, setH] = useState(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: 'flex', alignItems: 'center', gap: 12, width: '100%', padding: '11px 14px',
        borderRadius: 12, border: 'none', cursor: 'pointer', fontFamily: 'var(--font)',
        fontSize: 14.5, fontWeight: active ? 700 : 500, textAlign: 'left',
        color: active ? 'var(--text)' : 'var(--text-2)',
        background: active ? 'var(--surface-2)' : (h ? 'var(--surface)' : 'transparent'),
        position: 'relative', transition: 'all .15s',
      }}>
      {active && <span style={{ position: 'absolute', left: -10, top: 12, bottom: 12, width: 3, borderRadius: 99, background: 'var(--accent)' }} />}
      <Icon name={icon} size={19} color={active ? 'var(--accent-ink)' : 'currentColor'} sw={active ? 2 : 1.8} />
      <span style={{ flex: 1 }}>{label}</span>
      {badge && <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--accent-ink)', background: 'var(--accent-wash)', padding: '1px 7px', borderRadius: 99 }}>{badge}</span>}
    </button>
  );
}

function MobileTabBar({ nav, setNav }) {
  const items = [
    { view: 'explore', icon: 'explore', label: 'Explore' },
    { view: 'leaderboard', icon: 'gauge', label: 'Ranks' },
    { view: 'portfolio', icon: 'wallet', label: 'Portfolio' },
    { view: 'kol', icon: 'basket', label: 'Studio' },
    { view: 'activity', icon: 'bolt', label: 'Activity' },
  ];
  return (
    <nav style={{
      position: 'fixed', left: 0, right: 0, bottom: 0, zIndex: 60,
      display: 'flex', borderTop: '1px solid var(--line)',
      background: 'var(--chrome)', backdropFilter: 'blur(16px)',
      paddingBottom: 'env(safe-area-inset-bottom, 0px)',
    }}>
      {items.map(it => {
        const active = nav.view === it.view;
        return (
          <button key={it.view} onClick={() => setNav({ view: it.view })} style={{
            flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
            padding: '10px 0 12px', border: 'none', background: 'transparent', cursor: 'pointer',
            fontFamily: 'var(--font)', fontSize: 10.5, fontWeight: active ? 700 : 500,
            color: active ? 'var(--accent-ink)' : 'var(--text-3)',
          }}>
            <Icon name={it.icon} size={21} color={active ? 'var(--accent-ink)' : 'var(--text-3)'} sw={active ? 2 : 1.8} />
            {it.label}
          </button>
        );
      })}
    </nav>
  );
}

function walletUsdcValue(dataState, auth) {
  if (!auth || !auth.connected) return 0;
  if (dataState && dataState.walletUsdcBalance != null) return Number(dataState.walletUsdcBalance) || 0;
  if (dataState && dataState.walletBalances && dataState.walletBalances.totals) {
    return Number(dataState.walletBalances.totals.usdc) || 0;
  }
  return 0;
}

function walletDisplay(auth) {
  const wallet = auth && auth.wallet;
  if (!wallet) return { label: 'Wallet', detail: 'Not connected', chain: 'sol' };
  return {
    label: wallet.label || 'Wallet',
    detail: wallet.short || wallet.address || 'connected',
    chain: wallet.chain === 'base' ? 'base' : 'sol',
  };
}

function ConnectionStatusPill({ dataState }) {
  const mode = dataState && dataState.mode;
  const online = dataState && dataState.online;
  const live = mode === 'live';
  const liveEmpty = mode === 'live_empty';
  const col = live ? 'var(--accent-ink)' : online ? 'var(--blue)' : 'var(--warning)';
  const label = live ? 'Live API' : liveEmpty ? 'Live API empty' : online ? 'Demo data' : 'Offline';
  return (
    <span title={(dataState && dataState.message) || ''} style={{
      display: 'inline-flex', alignItems: 'center', gap: 7, padding: '7px 10px', borderRadius: 999,
      border: '1px solid var(--line)', background: 'var(--surface)', color: col,
      fontSize: 12, fontWeight: 700, whiteSpace: 'nowrap',
      minWidth: 0, maxWidth: '100%', overflow: 'hidden',
    }}>
      <span style={{ width: 7, height: 7, borderRadius: 99, background: col, flexShrink: 0 }} />
      <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{label}</span>
    </span>
  );
}

function ConnectionPill({ dataState, auth, onConnectX, compact = false }) {
  const authLabel = 'Connect wallet';
  const connectedWallet = walletDisplay(auth);
  const walletText = compact ? 'Wallet' : `${connectedWallet.label} ${connectedWallet.detail}`;
  return (
    <div style={{
      display: 'inline-flex',
      alignItems: 'center',
      gap: 8,
      minWidth: 0,
      maxWidth: compact ? 92 : 'min(100%, 320px)',
      flexWrap: 'nowrap',
      overflow: 'hidden',
      flexShrink: 1,
    }}>
      {!compact && <ConnectionStatusPill dataState={dataState} />}
      {auth && auth.connected ? (
        <button onClick={onConnectX} title="Add or switch wallet" style={{
          display: 'inline-flex', alignItems: 'center', gap: 7, padding: compact ? '7px 9px' : '7px 11px',
          borderRadius: 999, border: '1px solid rgba(163,255,91,0.3)', background: 'var(--accent-wash)',
          color: 'var(--accent-ink)', cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 12, fontWeight: 700,
          minWidth: 0, maxWidth: compact ? 92 : 190, overflow: 'hidden',
        }}>
          <WalletBrandIcon id={connectedWallet.label} label={connectedWallet.label} chain={connectedWallet.chain} size={compact ? 18 : 20} />
          <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{walletText}</span>
        </button>
      ) : (
        <button onClick={onConnectX} title="Connect wallet" style={{
          display: 'inline-flex', alignItems: 'center', gap: 7, padding: compact ? '7px 9px' : '7px 11px',
          borderRadius: 999, border: '1px solid var(--line-2)', background: 'var(--surface)',
          color: 'var(--text-2)', cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 12, fontWeight: 700,
          minWidth: 0, maxWidth: '100%',
        }}>
          <Icon name="wallet" size={13} color="currentColor" style={{ flexShrink: 0 }} />
          <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{compact ? 'Wallet' : authLabel}</span>
        </button>
      )}
    </div>
  );
}

function MobileTopBar({ onSearch, dataState, auth, onConnectX, onLogout }) {
  const balance = walletUsdcValue(dataState, auth);
  return (
    <header style={{
      display: 'flex', alignItems: 'center', gap: 12, padding: '0 16px', height: 58,
      position: 'sticky', top: 0, zIndex: 30, borderBottom: '1px solid var(--line)',
      background: 'var(--chrome)', backdropFilter: 'blur(14px)',
    }}>
      <Logo size={24} />
      <div style={{ flex: 1 }} />
      <ThemeToggle size={38} />
      <ConnectionPill compact dataState={dataState} auth={auth} onConnectX={onConnectX} />
      <button onClick={onSearch} aria-label="Search" style={{ width: 38, height: 38, borderRadius: 10, border: '1px solid var(--line)', background: 'var(--surface)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <Icon name="explore" size={18} color="var(--text-2)" />
      </button>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 6px 5px 12px', borderRadius: 999, border: '1px solid var(--line)', background: 'var(--surface)' }}>
        <span className="tnum" style={{ fontSize: 12.5, fontWeight: 600 }}>{fmtCompact(balance)}</span>
        <div style={{ width: 26, height: 26, borderRadius: '50%', background: 'radial-gradient(120% 120% at 30% 20%, var(--blue), #3a4ad0)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: 11, color: '#fff' }}>JN</div>
      </div>
    </header>
  );
}

function AppShell({ nav, setNav, children, onSearch, onCmdk, dataState, activity = [], auth, onConnectX, onLogout }) {
  const isMobile = useIsMobile();
  const balance = walletUsdcValue(dataState, auth);
  const wallet = walletDisplay(auth);
  if (isMobile) {
    return (
      <div className="ambient" style={{ minHeight: '100vh', background: 'var(--bg)' }}>
        <MobileTopBar onSearch={onSearch} dataState={dataState} auth={auth} onConnectX={onConnectX} onLogout={onLogout} />
        <div style={{ paddingBottom: 78 }}>{children}</div>
        <MobileTabBar nav={nav} setNav={setNav} />
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: 'var(--bg)' }}>
      {/* sidebar */}
      <aside style={{
        width: 248, flexShrink: 0, borderRight: '1px solid var(--line)', padding: '22px 18px',
        display: 'flex', flexDirection: 'column', gap: 6, position: 'sticky', top: 0, height: '100vh',
        background: 'linear-gradient(180deg, var(--bg-2), var(--bg))',
      }}>
        <div style={{ padding: '4px 8px 22px' }}>
          <Logo size={28} />
        </div>
        <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--text-3)', padding: '4px 14px 8px' }}>Menu</div>
        <NavItem icon="explore" label="Explore" active={nav.view === 'explore'} onClick={() => setNav({ view: 'explore' })} />
        <NavItem icon="gauge" label="Leaderboard" active={nav.view === 'leaderboard'} onClick={() => setNav({ view: 'leaderboard' })} />
        <NavItem icon="wallet" label="Portfolio" active={nav.view === 'portfolio'} onClick={() => setNav({ view: 'portfolio' })} />
        <NavItem icon="basket" label="KOL Studio" active={nav.view === 'kol'} onClick={() => setNav({ view: 'kol' })} />
        <NavItem icon="bolt" label="Activity" active={nav.view === 'activity'} onClick={() => setNav({ view: 'activity' })} />

        <div style={{ marginTop: 'auto' }}>
          {/* wallet card */}
          <div style={{ background: 'var(--surface)', border: '1px solid var(--line)', borderRadius: 16, padding: 14 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
              <span style={{
                width: 8,
                height: 8,
                borderRadius: 99,
                background: auth && auth.connected ? 'var(--accent)' : 'var(--text-3)',
                boxShadow: auth && auth.connected ? '0 0 8px var(--accent-glow)' : 'none',
              }} />
              <span style={{ fontSize: 12, color: 'var(--text-2)', fontWeight: 600 }}>{auth && auth.connected ? 'Wallet connected' : 'No wallet connected'}</span>
            </div>
            <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 2 }}>USDC balance</div>
            <div className="tnum" style={{ fontSize: 20, fontWeight: 700, letterSpacing: '-0.02em' }}>{fmtUsd(balance)}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 8, fontSize: 11, color: 'var(--text-3)', minWidth: 0 }}>
              {auth && auth.connected && <WalletBrandIcon id={wallet.label} label={wallet.label} chain={wallet.chain} size={22} />}
              <span style={{ fontFamily: 'var(--mono)', minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{wallet.detail}</span>
              {auth && auth.connected && <ChainBadge chain={wallet.chain} size="sm" />}
            </div>
            <div style={{ marginTop: 12, display: 'grid', gap: 8 }}>
              <ConnectionStatusPill dataState={dataState} />
              {auth && auth.connected && (
                <button onClick={onLogout} style={{
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 7,
                  width: '100%', padding: '8px 10px', borderRadius: 10,
                  border: '1px solid rgba(255,91,91,0.26)', background: 'rgba(255,91,91,0.07)',
                  color: 'var(--danger)', cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 12, fontWeight: 800,
                }}>
                  Disconnect wallet
                </button>
              )}
            </div>
          </div>
        </div>
      </aside>

      {/* main */}
      <main className="ambient" style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }}>
        <TopBar nav={nav} setNav={setNav} onCmdk={onCmdk} dataState={dataState} activity={activity} auth={auth} onConnectX={onConnectX} onLogout={onLogout} />
        <div style={{ flex: 1 }}>{children}</div>
      </main>
    </div>
  );
}

function NotificationMenu({ items = [], onOpenActivity }) {
  const [open, setOpen] = useState(false);
  const shown = (items || []).slice(0, 6);
  const hasItems = shown.length > 0;
  return (
    <div style={{ position: 'relative', flexShrink: 0 }}>
      <button onClick={() => setOpen(v => !v)} aria-label="Notifications" style={{ position: 'relative', width: 40, height: 40, borderRadius: 11, border: '1px solid var(--line)', background: 'var(--surface)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <Icon name="bell" size={18} color="var(--text-2)" />
        {hasItems && <span style={{ position: 'absolute', top: 9, right: 10, width: 7, height: 7, borderRadius: 99, background: 'var(--accent)', border: '2px solid var(--surface)' }} />}
      </button>
      {open && (
        <div style={{ position: 'absolute', right: 0, top: 48, width: 340, maxWidth: 'calc(100vw - 48px)', background: 'var(--surface)', border: '1px solid var(--line-2)', borderRadius: 16, boxShadow: 'var(--shadow-lg)', padding: 10, zIndex: 80 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '7px 8px 10px' }}>
            <div style={{ fontSize: 14, fontWeight: 800 }}>Notifications</div>
            <button onClick={() => { setOpen(false); onOpenActivity && onOpenActivity(); }} style={{ border: 'none', background: 'transparent', color: 'var(--blue)', fontFamily: 'var(--font)', fontSize: 12, fontWeight: 800, cursor: 'pointer' }}>Open activity</button>
          </div>
          {hasItems ? shown.map((item, index) => (
            <div key={index} style={{ display: 'flex', gap: 10, padding: '10px 8px', borderTop: index ? '1px solid var(--line)' : 'none' }}>
              <div style={{ width: 30, height: 30, borderRadius: 9, flexShrink: 0, background: item.accent ? 'var(--accent-wash)' : 'var(--surface-2)', border: '1px solid var(--line)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name={item.kind === 'rebalance' ? 'swap' : item.kind === 'copy' ? 'copy' : item.kind === 'sell' ? 'arrowDn' : 'bolt'} size={14} color={item.accent ? 'var(--accent-ink)' : 'var(--text-2)'} />
              </div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 12.5, lineHeight: 1.35 }}><strong>{item.who}</strong> <span style={{ color: 'var(--text-2)' }}>{item.what}</span></div>
                <div className="data" style={{ marginTop: 3, fontSize: 10.5, color: 'var(--text-3)' }}>{item.when}</div>
              </div>
            </div>
          )) : (
            <div style={{ padding: '14px 8px 16px', fontSize: 13, color: 'var(--text-2)', lineHeight: 1.45 }}>No live notifications yet. Basket launches, rebalances, buys, and sells will appear here.</div>
          )}
        </div>
      )}
    </div>
  );
}

function TopBar({ nav, setNav, onCmdk, dataState, activity = [], auth, onConnectX, onLogout }) {
  const balance = walletUsdcValue(dataState, auth);
  return (
    <header style={{
      height: 68, minHeight: 68, maxHeight: 68, overflow: 'visible',
      borderBottom: '1px solid var(--line)', display: 'flex', alignItems: 'center',
      gap: 16, padding: '0 32px', position: 'sticky', top: 0, zIndex: 30,
      background: 'var(--chrome)', backdropFilter: 'blur(14px)',
    }}>
      <button className="top-search" onClick={onCmdk} style={{ position: 'relative', flex: '1 1 420px', minWidth: 190, maxWidth: 420, height: 42, display: 'flex', alignItems: 'center', gap: 10, padding: '0 14px', borderRadius: 12, border: '1px solid var(--line)', background: 'var(--surface)', cursor: 'pointer', fontFamily: 'var(--font)', color: 'var(--text-3)', fontSize: 14, overflow: 'hidden' }}>
        <Icon name="explore" size={17} color="var(--text-3)" style={{ flexShrink: 0 }} />
        <span style={{ flex: 1, textAlign: 'left' }}>Search baskets, KOLs, tokens…</span>
        <kbd style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-2)', border: '1px solid var(--line-2)', borderRadius: 6, padding: '2px 7px' }}>⌘K</kbd>
      </button>
      <div style={{ flex: 1 }} />
      <ConnectionPill dataState={dataState} auth={auth} onConnectX={onConnectX} />
      <NotificationMenu items={activity} onOpenActivity={() => setNav({ view: 'activity' })} />
      <ThemeToggle />
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '5px 6px 5px 14px', borderRadius: 999, border: '1px solid var(--line)', background: 'var(--surface)' }}>
        <span className="tnum" style={{ fontSize: 13, fontWeight: 600 }}>{fmtCompact(balance)}</span>
        <div style={{ width: 30, height: 30, borderRadius: '50%', background: 'radial-gradient(120% 120% at 30% 20%, var(--blue), #3a4ad0)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, fontSize: 12, color: '#fff' }}>JN</div>
      </div>
    </header>
  );
}

/* ---------------- Basket card ---------------- */
function BasketCard({ b, onOpen, rank }) {
  const [hov, setHov] = useState(false);
  const pos = b.perf7d >= 0;
  return (
    <Card hover onClick={() => onOpen(b.id)} pad={0} glow
      style={{ overflow: 'hidden' }}>
      <div className="spot" onMouseMove={spotlight} onMouseEnter={() => setHov(true)} onMouseLeave={() => setHov(false)}
        style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 15 }}>
        {/* header: rank + kol + chain */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
          {rank && <span className="data" style={{ fontSize: 12, color: 'var(--text-3)', fontWeight: 600 }}>{rank}</span>}
          <KolAvatar kol={b.kol} size={34} />
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ fontWeight: 700, fontSize: 13.5 }}>{b.kol.x}</div>
            <div className="eyebrow" style={{ fontSize: 10 }}>{b.kol.followers} followers</div>
          </div>
          {b.chainSplit.base > 0 ? <ChainBadge chain="base" size="sm" /> : <ChainBadge chain="sol" size="sm" />}
        </div>

        {/* name — the hero */}
        <div>
          <h3 className="display" style={{ margin: 0, fontSize: 23, fontWeight: 800, lineHeight: 1.04 }}>{b.name}</h3>
          <p style={{ margin: '6px 0 0', fontSize: 12.5, color: 'var(--text-2)', lineHeight: 1.45, display: '-webkit-box', WebkitLineClamp: 1, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}>{b.tagline}</p>
        </div>

        {/* perf block: big mono % + filling sparkline */}
        <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 12 }}>
          <div>
            <div className="eyebrow" style={{ marginBottom: 4 }}>7D return</div>
            <div className="data" style={{ fontSize: 30, fontWeight: 700, lineHeight: 0.9, letterSpacing: '-0.03em', color: pos ? 'var(--accent-ink)' : 'var(--danger)' }}>
              {sign(b.perf7d)}{Math.abs(b.perf7d).toFixed(1)}%
            </div>
          </div>
          <div style={{ flex: 1, maxWidth: 150 }}>
            <Sparkline data={b.spark} w={150} h={46} fill sw={2.4} color={pos ? 'var(--accent-ink)' : 'var(--danger)'} />
          </div>
        </div>

        {/* technical footer stat row */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr auto', alignItems: 'center', gap: 10, paddingTop: 14, borderTop: '1px solid var(--line)' }}>
          <div>
            <div className="eyebrow" style={{ fontSize: 9.5, marginBottom: 3 }}>AUM</div>
            <div className="data" style={{ fontSize: 14, fontWeight: 700 }}>{fmtCompact(b.aum)}</div>
          </div>
          <div>
            <div className="eyebrow" style={{ fontSize: 9.5, marginBottom: 3 }}>Copiers</div>
            <div className="data" style={{ fontSize: 14, fontWeight: 700 }}>{b.copiers.toLocaleString()}</div>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <TokenStack tokens={b.tokens} size={26} max={4} />
            <span style={{ width: 30, height: 30, borderRadius: 9, background: hov ? 'var(--accent)' : 'var(--surface-2)', border: '1px solid ' + (hov ? 'var(--accent)' : 'var(--line)'), display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all .25s cubic-bezier(.22,1,.3,1)', transform: hov ? 'translateX(0)' : 'translateX(-2px)' }}>
              <Icon name="arrowR" size={15} color={hov ? 'var(--on-accent)' : 'var(--text-2)'} sw={2.2} />
            </span>
          </div>
        </div>
      </div>
    </Card>
  );
}

/* ---------------- Explore screen ---------------- */
function ExploreScreen({ onOpen, sheetOpen, setSheetOpen }) {
  const { baskets } = window.DB;
  const isMobile = useIsMobile();
  const [filter, setFilter] = useState('All');
  const [sort, setSort] = useState('Top performing');
  const [query, setQuery] = useState('');
  const filters = ['All', 'Solana only', 'Two-chain', 'DeFi', 'Memes', 'Yield', 'AI'];
  const featured = baskets[0];

  const cat = (b) => {
    if (filter === 'Solana only') return b.chainSplit.base === 0;
    if (filter === 'Two-chain') return b.chainSplit.base > 0;
    if (filter === 'Memes') return b.id.includes('meme') || b.id.includes('degen') && b.id !== 'degen-majors';
    if (filter === 'Yield') return b.id.includes('staking') || b.id.includes('barbell');
    if (filter === 'AI') return b.id.includes('ai');
    return true;
  };
  const q = query.trim().toLowerCase();
  const matchesQ = (b) => !q || b.name.toLowerCase().includes(q) || b.kol.x.toLowerCase().includes(q) ||
    b.kol.name.toLowerCase().includes(q) || b.tokens.some(t => t.sym.toLowerCase().includes(q));
  let list = baskets.filter(b => cat(b) && matchesQ(b));
  if (sort === 'Top performing') list = [...list].sort((a, b) => b.perf7d - a.perf7d);
  if (sort === 'Largest AUM') list = [...list].sort((a, b) => b.aum - a.aum);
  if (sort === 'Most copiers') list = [...list].sort((a, b) => b.copiers - a.copiers);

  const activeCount = (filter !== 'All' ? 1 : 0) + (sort !== 'Top performing' ? 1 : 0) + (q ? 1 : 0);
  const sorts = ['Top performing', 'Largest AUM', 'Most copiers'];
  const apiState = (window.DB && window.DB.api) || {};

  if (!featured) {
    return (
      <div className="page" style={{ padding: '32px 32px 64px', maxWidth: 980, margin: '0 auto' }}>
        <section className="grain ticks" style={{
          position: 'relative', overflow: 'hidden', borderRadius: 'var(--r-xl)', border: '1px solid var(--line-2)',
          background: 'var(--bg-2)', boxShadow: 'var(--shadow)', padding: '42px 40px',
        }}>
          <div className="eyebrow" style={{ color: apiState.online ? 'var(--accent-ink)' : 'var(--warning)', marginBottom: 14 }}>
            {apiState.online ? 'Live backend connected' : 'Backend offline'}
          </div>
          <h1 className="display" style={{ margin: 0, fontSize: 'clamp(32px, 4vw, 52px)', fontWeight: 900, lineHeight: 1 }}>
            No live baskets yet.
          </h1>
          <p style={{ margin: '18px 0 0', color: 'var(--text-2)', fontSize: 16, lineHeight: 1.55, maxWidth: 620 }}>
            {apiState.message || 'Demo data is disabled for this production-like run. Connect X as a KOL and launch a basket, or point the frontend at a backend database that already has active baskets.'}
          </p>
          <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginTop: 28, flexWrap: 'wrap' }}>
            <Btn size="lg" icon="basket" onClick={() => window.dispatchEvent(new CustomEvent('basket:navigate', { detail: { view: 'kol' } }))}>Open KOL Studio</Btn>
          </div>
        </section>
      </div>
    );
  }

  return (
    <div className="page" style={{ padding: '32px 32px 64px', maxWidth: 1280, margin: '0 auto' }}>
      {/* mobile search + filters bottom-sheet */}
      {isMobile && (
        <BottomSheet open={sheetOpen} onClose={() => setSheetOpen(false)} title="Search & filter">
          <div style={{ position: 'relative', marginBottom: 20 }}>
            <Icon name="explore" size={18} color="var(--text-3)" style={{ position: 'absolute', left: 14, top: '50%', transform: 'translateY(-50%)' }} />
            <input autoFocus value={query} onChange={e => setQuery(e.target.value)} placeholder="Search baskets, KOLs, tokens…" style={{
              width: '100%', padding: '13px 14px 13px 42px', borderRadius: 12, border: '1px solid var(--line-2)',
              background: 'var(--bg-2)', color: 'var(--text)', fontFamily: 'var(--font)', fontSize: 15, outline: 'none',
            }} />
            {query && <button onClick={() => setQuery('')} style={{ position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)', width: 28, height: 28, borderRadius: 8, border: 'none', background: 'var(--surface-2)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Icon name="x" size={14} color="var(--text-2)" /></button>}
          </div>
          <div style={{ fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-3)', marginBottom: 10, fontWeight: 600 }}>Category</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 22 }}>
            {filters.map(f => <Chip key={f} active={filter === f} onClick={() => setFilter(f)}>{f}</Chip>)}
          </div>
          <div style={{ fontSize: 12, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--text-3)', marginBottom: 10, fontWeight: 600 }}>Sort by</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginBottom: 22 }}>
            {sorts.map(s => <Chip key={s} active={sort === s} onClick={() => setSort(s)} dot={sort === s} color="var(--accent)">{s}</Chip>)}
          </div>
          <div style={{ display: 'flex', gap: 10, paddingTop: 6 }}>
            <Btn variant="ghost" full onClick={() => { setFilter('All'); setSort('Top performing'); setQuery(''); }}>Reset</Btn>
            <Btn full onClick={() => setSheetOpen(false)}>Show {list.length} baskets</Btn>
          </div>
        </BottomSheet>
      )}

      {/* ===== editorial hero ===== */}
      <section className="grain ticks" style={{
        position: 'relative', overflow: 'hidden', borderRadius: 'var(--r-xl)', border: '1px solid var(--line-2)',
        background: 'var(--bg-2)', marginBottom: 16, boxShadow: 'var(--shadow)',
      }}>
        {/* sharp corner mesh */}
        <div style={{ position: 'absolute', top: -120, right: -80, width: 460, height: 460, background: 'radial-gradient(circle at 60% 40%, var(--accent-glow), transparent 62%)', opacity: 0.6, pointerEvents: 'none', animation: 'meshShift 24s ease-in-out infinite' }} />
        <div style={{ position: 'absolute', bottom: -160, left: 180, width: 360, height: 360, background: 'radial-gradient(circle, var(--blue-wash), transparent 64%)', opacity: 0.7, pointerEvents: 'none', filter: 'blur(6px)', animation: 'meshShift 30s ease-in-out infinite reverse' }} />

        <div className="hero" style={{ position: 'relative', zIndex: 1, display: 'grid', gridTemplateColumns: '1.18fr 0.82fr' }}>
          {/* left editorial block */}
          <div style={{ padding: '34px 40px 36px', borderRight: '1px solid var(--line)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 28 }}>
              <span className="eyebrow" style={{ color: 'var(--accent-ink)' }}>01 — Marketplace</span>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 11, fontFamily: 'var(--mono)', letterSpacing: '0.12em', color: 'var(--text-3)' }}>
                <span style={{ width: 6, height: 6, borderRadius: 99, background: 'var(--accent)', boxShadow: '0 0 8px var(--accent)', animation: 'pulse 1.6s infinite' }} />LIVE
              </span>
            </div>

            <Kinetic
              style={{ fontSize: 'clamp(34px, 3.5vw, 52px)', fontWeight: 900 }}
              lineStyle={{ paddingBottom: 2 }}
              lines={[
                <span key="1">Follow the <span style={{ color: 'var(--accent-ink)' }}>basket.</span></span>,
                <span key="2" style={{ fontWeight: 300, color: 'var(--text-2)' }}>Skip the noise.</span>,
              ]}
            />

            <p style={{ margin: '24px 0 28px', fontSize: 16.5, color: 'var(--text-2)', maxWidth: 460, lineHeight: 1.55 }}>
              Copy an entire KOL portfolio in one click. We buy the real underlying assets — you hold basket units that track every rebalance, automatically.
            </p>

            <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
              <Magnetic><Btn size="lg" icon="copy" onClick={() => onOpen(featured.id)}>Start copying</Btn></Magnetic>
              <Btn size="lg" variant="ghost" iconR="arrowR">How it works</Btn>
            </div>

            {/* technical stat strip */}
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', marginTop: 38, borderTop: '1px solid var(--line)' }}>
              {[
                { to: 8.2, fmt: n => '$' + n.toFixed(1) + 'M', label: 'Total AUM' },
                { to: 6.4, fmt: n => n.toFixed(1) + 'K', label: 'Copiers' },
                { to: 148, fmt: n => Math.round(n), label: 'KOL baskets' },
              ].map((s, i) => (
                <div key={i} style={{ padding: '18px 18px 0 0', borderRight: i < 2 ? '1px solid var(--line)' : 'none', paddingLeft: i ? 22 : 0 }}>
                  <div className="data" style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.03em' }}><CountUp to={s.to} dur={1400} format={s.fmt} /></div>
                  <div className="eyebrow" style={{ marginTop: 4 }}>{s.label}</div>
                </div>
              ))}
            </div>
          </div>

          {/* right featured panel */}
          <div onClick={() => onOpen(featured.id)} onMouseMove={spotlight} className="spot sheen"
            style={{ position: 'relative', cursor: 'pointer', padding: '30px 30px 26px', display: 'flex', flexDirection: 'column', background: 'linear-gradient(180deg, var(--surface) 0%, var(--bg-2) 100%)' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 22 }}>
              <span className="eyebrow">★ Featured basket</span>
              <span style={{ fontSize: 11, fontFamily: 'var(--mono)', color: 'var(--text-3)' }}>v{featured.version}</span>
            </div>

            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
              <KolAvatar kol={featured.kol} size={46} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 800, fontSize: 19, letterSpacing: '-0.02em' }}>{featured.name}</div>
                <div style={{ fontSize: 13, color: 'var(--text-3)' }}>by {featured.kol.x}</div>
              </div>
            </div>

            <div style={{ display: 'flex', alignItems: 'flex-end', gap: 14, marginBottom: 4 }}>
              <div className="data" style={{ fontSize: 46, fontWeight: 700, color: featured.perf30d >= 0 ? 'var(--accent-ink)' : 'var(--danger)', lineHeight: 0.9, letterSpacing: '-0.04em' }}>
                {sign(featured.perf30d)}{Math.abs(featured.perf30d).toFixed(1)}%
              </div>
              <span className="eyebrow" style={{ paddingBottom: 6 }}>30D return</span>
            </div>

            <div style={{ margin: '14px -6px 0', flex: 1, minHeight: 96, display: 'flex', alignItems: 'flex-end' }}>
              <AreaChart data={featured.spark} h={120} color="var(--accent-ink)" showAxis={false} />
            </div>

            <div style={{ marginTop: 18, paddingTop: 16, borderTop: '1px solid var(--line)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <TokenStack tokens={featured.tokens} size={28} />
              <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text)', display: 'inline-flex', alignItems: 'center', gap: 5 }}>Open <Icon name="arrowR" size={15} color="var(--accent-ink)" /></span>
            </div>
          </div>
        </div>
      </section>

      {/* ticker tape under hero */}
      <div style={{ borderRadius: 14, overflow: 'hidden', border: '1px solid var(--line)', marginBottom: 30 }}>
        <TickerTape />
      </div>

      <SectionLabel n="02" right={!isMobile && <span className="eyebrow">{list.length} live</span>}>All baskets</SectionLabel>

      {/* filter row */}
      {isMobile ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
          <button onClick={() => setSheetOpen(true)} style={{
            flex: 1, display: 'flex', alignItems: 'center', gap: 10, padding: '12px 14px', borderRadius: 12,
            border: '1px solid var(--line)', background: 'var(--surface)', cursor: 'pointer', fontFamily: 'var(--font)',
            color: query ? 'var(--text)' : 'var(--text-3)', fontSize: 14.5, textAlign: 'left',
          }}>
            <Icon name="explore" size={18} color="var(--text-3)" />
            <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{query || 'Search baskets, KOLs, tokens…'}</span>
          </button>
          <button onClick={() => setSheetOpen(true)} style={{
            position: 'relative', display: 'inline-flex', alignItems: 'center', gap: 7, padding: '12px 15px', borderRadius: 12,
            border: '1px solid ' + (activeCount ? 'var(--accent)' : 'var(--line-2)'), background: activeCount ? 'var(--accent-wash)' : 'var(--surface)',
            cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 14, fontWeight: 700, color: activeCount ? 'var(--accent-ink)' : 'var(--text)',
          }}>
            <Icon name="list" size={17} color={activeCount ? 'var(--accent-ink)' : 'var(--text-2)'} />
            Filters
            {activeCount > 0 && <span style={{ minWidth: 18, height: 18, padding: '0 5px', borderRadius: 99, background: 'var(--accent)', color: 'var(--on-accent)', fontSize: 11, fontWeight: 800, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>{activeCount}</span>}
          </button>
        </div>
      ) : (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20, gap: 16, flexWrap: 'wrap' }}>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {filters.map(f => <Chip key={f} active={filter === f} onClick={() => setFilter(f)}>{f}</Chip>)}
          </div>
          <div style={{ display: 'flex', gap: 8 }}>
            {['Top performing', 'Largest AUM', 'Most copiers'].map(s => (
              <Chip key={s} active={sort === s} onClick={() => setSort(s)} dot={sort === s} color="var(--accent)">{s}</Chip>
            ))}
          </div>
        </div>
      )}

      {/* empty state */}
      {list.length === 0 && (
        <div style={{ textAlign: 'center', padding: '60px 20px', color: 'var(--text-3)' }}>
          <div style={{ display: 'inline-flex', width: 54, height: 54, borderRadius: 16, background: 'var(--surface-2)', alignItems: 'center', justifyContent: 'center', marginBottom: 14 }}>
            <Icon name="explore" size={24} color="var(--text-3)" />
          </div>
          <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--text-2)' }}>No baskets match</div>
          <div style={{ fontSize: 13.5, marginTop: 4 }}>Try a different search or clear your filters.</div>
        </div>
      )}

      {/* grid */}
      <div className="card-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(330px, 1fr))', gap: 18 }}>
        {list.map((b, i) => (
          <Reveal key={b.id} delay={(i % 3) * 80}>
            <BasketCard b={b} onOpen={onOpen} rank={String(i + 1).padStart(2, '0')} />
          </Reveal>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { AppShell, ExploreScreen, BasketCard, NavItem });
