/* ============================================================
   basket.fun — Command palette (⌘K), KOL profile, Leaderboard
   ============================================================ */

/* ---------------- Command palette (⌘K) ---------------- */
function CommandPalette({ open, onClose, onNav, onOpenBasket, onOpenKol }) {
  const { baskets } = window.DB;
  const [q, setQ] = useState('');
  const [sel, setSel] = useState(0);
  const inputRef = useRef(null);

  const actions = useMemo(() => {
    const navs = [
      { kind: 'nav', label: 'Explore', hint: 'Marketplace', icon: 'explore', run: () => onNav('explore') },
      { kind: 'nav', label: 'Leaderboard', hint: 'Rankings', icon: 'gauge', run: () => onNav('leaderboard') },
      { kind: 'nav', label: 'Portfolio', hint: 'Your positions', icon: 'wallet', run: () => onNav('portfolio') },
      { kind: 'nav', label: 'KOL Studio', hint: 'Creator tools', icon: 'basket', run: () => onNav('kol') },
      { kind: 'nav', label: 'Activity', hint: 'Live feed', icon: 'bolt', run: () => onNav('activity') },
    ];
    const bk = baskets.map(b => ({ kind: 'basket', label: b.name, hint: 'by ' + b.kol.x, b, icon: 'basket', run: () => onOpenBasket(b.id) }));
    const kols = [...new Map(baskets.map(b => [b.kol.handle, b.kol])).values()]
      .map(k => ({ kind: 'kol', label: k.x, hint: k.name + ' · ' + k.followers, k, icon: 'user', run: () => onOpenKol(k.handle) }));
    return [...navs, ...bk, ...kols];
  }, []);

  const ql = q.trim().toLowerCase();
  const results = ql
    ? actions.filter(a => a.label.toLowerCase().includes(ql) || (a.hint || '').toLowerCase().includes(ql))
    : actions;

  useEffect(() => { setSel(0); }, [q]);
  useEffect(() => { if (open) { setQ(''); setTimeout(() => inputRef.current && inputRef.current.focus(), 40); } }, [open]);
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'ArrowDown') { e.preventDefault(); setSel(s => Math.min(results.length - 1, s + 1)); }
      else if (e.key === 'ArrowUp') { e.preventDefault(); setSel(s => Math.max(0, s - 1)); }
      else if (e.key === 'Enter') { e.preventDefault(); const r = results[sel]; if (r) { r.run(); onClose(); } }
      else if (e.key === 'Escape') { onClose(); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, results, sel]);

  if (!open) return null;
  const groups = [
    { key: 'nav', label: 'Navigate' },
    { key: 'basket', label: 'Baskets' },
    { key: 'kol', label: 'Creators' },
  ];
  let runningIndex = -1;

  return (
    <Portal>
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 95, background: 'rgba(5,6,11,0.6)', backdropFilter: 'blur(5px)', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', padding: '12vh 20px 20px', animation: 'fadeIn .16s ease forwards' }}>
      <div onClick={e => e.stopPropagation()} className="surface-grad" style={{ width: '100%', maxWidth: 580, borderRadius: 18, border: '1px solid var(--line-2)', boxShadow: 'var(--shadow-lg)', overflow: 'hidden', animation: 'cmdIn .22s cubic-bezier(.16,1,.3,1) forwards' }}>
        {/* search */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '16px 18px', borderBottom: '1px solid var(--line)' }}>
          <Icon name="explore" size={20} color="var(--text-3)" />
          <input ref={inputRef} value={q} onChange={e => setQ(e.target.value)} placeholder="Search baskets, creators, pages…"
            style={{ flex: 1, border: 'none', background: 'transparent', color: 'var(--text)', fontFamily: 'var(--font)', fontSize: 16, outline: 'none' }} />
          <kbd style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-3)', border: '1px solid var(--line-2)', borderRadius: 6, padding: '2px 7px' }}>ESC</kbd>
        </div>
        {/* results */}
        <div style={{ maxHeight: '52vh', overflowY: 'auto', padding: 8 }}>
          {results.length === 0 && (
            <div style={{ padding: '32px 16px', textAlign: 'center', color: 'var(--text-3)', fontSize: 14 }}>No matches for “{q}”.</div>
          )}
          {groups.map(g => {
            const items = results.filter(r => r.kind === g.key);
            if (!items.length) return null;
            return (
              <div key={g.key} style={{ marginBottom: 6 }}>
                <div className="eyebrow" style={{ padding: '8px 12px 4px' }}>{g.label}</div>
                {items.map((r) => {
                  runningIndex++;
                  const idx = runningIndex;
                  const active = idx === sel;
                  return (
                    <button key={g.key + r.label} onMouseEnter={() => setSel(idx)} onClick={() => { r.run(); onClose(); }}
                      style={{ display: 'flex', alignItems: 'center', gap: 12, width: '100%', padding: '10px 12px', borderRadius: 11, border: 'none', cursor: 'pointer', textAlign: 'left',
                        background: active ? 'var(--surface-2)' : 'transparent', fontFamily: 'var(--font)', transition: 'background .12s' }}>
                      {r.kind === 'kol' && r.k ? <KolAvatar kol={r.k} size={26} />
                        : r.kind === 'basket' && r.b ? <TokenStack tokens={r.b.tokens} size={22} max={3} />
                        : <span style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon name={r.icon} size={15} color={active ? 'var(--accent-ink)' : 'var(--text-2)'} /></span>}
                      <span style={{ flex: 1, fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>{r.label}</span>
                      <span style={{ fontSize: 12, color: 'var(--text-3)' }}>{r.hint}</span>
                      {active && <Icon name="arrowR" size={14} color="var(--accent-ink)" />}
                    </button>
                  );
                })}
              </div>
            );
          })}
        </div>
        {/* footer */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '10px 16px', borderTop: '1px solid var(--line)', fontSize: 11.5, color: 'var(--text-3)' }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><kbd style={kbdS}>↑</kbd><kbd style={kbdS}>↓</kbd> navigate</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}><kbd style={kbdS}>↵</kbd> open</span>
          <span style={{ marginLeft: 'auto', fontFamily: 'var(--mono)' }}>basket.fun</span>
        </div>
      </div>
    </div>
    </Portal>
  );
}
const kbdS = { fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--text-2)', border: '1px solid var(--line-2)', borderRadius: 5, padding: '1px 5px', minWidth: 18, textAlign: 'center', display: 'inline-block' };

function kolXProfileUrl(handle) {
  const h = String(handle || '').replace('@', '').trim();
  return h ? `https://x.com/${encodeURIComponent(h)}` : 'https://x.com/';
}

function useKolFollowState(handle) {
  const key = 'basket.followedKols';
  const clean = String(handle || '').replace('@', '').trim();
  const [following, setFollowing] = useState(false);
  useEffect(() => {
    try {
      const stored = JSON.parse(localStorage.getItem(key) || '[]');
      setFollowing(stored.includes(clean));
    } catch (e) {
      setFollowing(false);
    }
  }, [clean]);
  const toggle = () => {
    setFollowing((current) => {
      let stored = [];
      try { stored = JSON.parse(localStorage.getItem(key) || '[]'); } catch (e) { stored = []; }
      const next = current ? stored.filter(item => item !== clean) : Array.from(new Set([...stored, clean]));
      try { localStorage.setItem(key, JSON.stringify(next)); } catch (e) {}
      return !current;
    });
  };
  return [following, toggle];
}

/* ---------------- KOL profile ---------------- */
function KolProfile({ handle, onBack, onOpenBasket, onCopy }) {
  const { baskets, kolBios, activity } = window.DB;
  const h = handle.replace('@', '');
  const mine = baskets.filter(b => b.kol.handle === h);
  const kol = (mine[0] || baskets[0]).kol;
  const [following, toggleFollow] = useKolFollowState(kol.handle);
  const bio = kolBios[h] || '';
  const totalAum = mine.reduce((s, b) => s + b.aum, 0);
  const totalCopiers = mine.reduce((s, b) => s + b.copiers, 0);
  const avg7d = mine.reduce((s, b) => s + b.perf7d, 0) / (mine.length || 1);
  const best = [...mine].sort((a, b) => b.perfAll - a.perfAll)[0];
  const feed = activity.filter(a => a.who === kol.x).concat([
    { kind: 'rebalance', who: kol.x, what: `rebalanced ${mine[0]?.name} to v${mine[0]?.version}`, when: '2d ago', accent: true },
    { kind: 'copy', who: '@0xmara', what: `copied ${mine[0]?.name} · $750`, when: '5h ago' },
    { kind: 'thesis', who: kol.x, what: `updated thesis on ${best?.name}`, when: '3d ago' },
  ]);
  const iconFor = { rebalance: 'swap', copy: 'copy', fill: 'check', sell: 'arrowDn', thesis: 'spark' };

  return (
    <div className="page" style={{ padding: '24px 32px 64px', maxWidth: 1180, margin: '0 auto', animation: 'fadeIn .35s ease .06s forwards' }}>
      <button onClick={onBack} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, background: 'none', border: 'none', color: 'var(--text-2)', cursor: 'pointer', fontFamily: 'var(--font)', fontSize: 14, fontWeight: 600, marginBottom: 22, padding: 0 }}>
        <Icon name="arrowR" size={16} color="var(--text-2)" style={{ transform: 'rotate(180deg)' }} /> Back
      </button>

      {/* profile header */}
      <Card pad={0} spot style={{ overflow: 'hidden', marginBottom: 24 }}>
        <div style={{ height: 96, background: `linear-gradient(120deg, ${kol.avatar}33, var(--blue-wash)), var(--bg-2)`, position: 'relative' }} className="grain" />
        <div style={{ padding: '0 28px 26px', marginTop: -38 }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 20, flexWrap: 'wrap' }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 18, minWidth: 0, flex: '1 1 420px' }}>
              <div style={{ borderRadius: '50%', border: '4px solid var(--surface)' }}><KolAvatar kol={kol} size={84} /></div>
              <div style={{ minWidth: 0, paddingTop: 42 }}>
                <h1 className="display" style={{ margin: 0, fontSize: 'clamp(26px,3vw,38px)', fontWeight: 900, lineHeight: 1.16, overflowWrap: 'anywhere' }}>{kol.name}</h1>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4, color: 'var(--text-2)', fontSize: 14, minWidth: 0, maxWidth: '100%', overflow: 'hidden', flexWrap: 'wrap' }}>
                  <span className="data">{kol.x}</span><span style={{ color: 'var(--text-3)' }}>·</span>
                  <span className="data">{kol.followers} followers</span>
                </div>
              </div>
            </div>
            <div style={{ display: 'flex', gap: 10, paddingTop: 46, paddingBottom: 4 }}>
              <Btn variant={following ? 'soft' : 'ghost'} icon={following ? 'check' : 'bell'} onClick={toggleFollow}>{following ? 'Following' : 'Follow'}</Btn>
              <Btn variant="ghost" iconR="ext" onClick={() => window.open(kolXProfileUrl(kol.handle), '_blank', 'noopener,noreferrer')}>View on X</Btn>
            </div>
          </div>
          {bio && <p style={{ margin: '18px 0 0', fontSize: 15.5, color: 'var(--text)', lineHeight: 1.55, maxWidth: 640 }}>{bio}</p>}
          <div className="g4" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 16, marginTop: 22, paddingTop: 20, borderTop: '1px solid var(--line)' }}>
            <Stat label="Total AUM" value={fmtCompact(totalAum)} />
            <Stat label="Copiers" value={totalCopiers.toLocaleString()} />
            <Stat label="Avg 7D" value={fmtPct(avg7d)} accent={avg7d >= 0} />
            <Stat label="Baskets" value={mine.length} />
          </div>
        </div>
      </Card>

      <SectionLabel n="01" right={<span className="eyebrow">{mine.length} live</span>}>Baskets by {kol.x}</SectionLabel>
      <div className="card-grid" style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(330px, 1fr))', gap: 18, marginBottom: 32 }}>
        {mine.map((b, i) => (
          <Reveal key={b.id} delay={(i % 3) * 70}><BasketCard b={b} onOpen={onOpenBasket} rank={String(i + 1).padStart(2, '0')} /></Reveal>
        ))}
      </div>

      <SectionLabel n="02">Recent activity</SectionLabel>
      <Card pad={8}>
        {feed.map((a, i) => (
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '13px 16px', borderBottom: i < feed.length - 1 ? '1px solid var(--line)' : 'none' }}>
            <div style={{ width: 36, height: 36, borderRadius: 10, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: a.accent ? 'var(--accent-wash)' : 'var(--surface-2)', border: '1px solid ' + (a.accent ? 'rgba(163,255,91,0.25)' : 'var(--line)') }}>
              <Icon name={iconFor[a.kind] || 'bolt'} size={16} color={a.accent ? 'var(--accent-ink)' : 'var(--text-2)'} />
            </div>
            <div style={{ flex: 1, fontSize: 14 }}><strong>{a.who}</strong> <span style={{ color: 'var(--text-2)' }}>{a.what}</span></div>
            <span className="data" style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{a.when}</span>
          </div>
        ))}
      </Card>
    </div>
  );
}

/* ---------------- Leaderboard ---------------- */
function Leaderboard({ onOpenBasket, onOpenKol }) {
  const { baskets } = window.DB;
  const isMobile = useIsMobile();
  const loading = useFakeLoad(650);
  const [sortKey, setSortKey] = useState('perf7d');
  const [dir, setDir] = useState(-1);
  const [tf, setTf] = useState('perf7d');

  const cols = [
    { key: 'rank', label: '#', w: '34px', sortable: false },
    { key: 'name', label: 'Basket', w: '2fr', sortable: true },
    { key: tf, label: tf === 'perf7d' ? '7D' : tf === 'perf30d' ? '30D' : 'All', w: '1fr', sortable: true, num: true },
    { key: 'aum', label: 'AUM', w: '1fr', sortable: true, num: true },
    { key: 'copiers', label: 'Copiers', w: '1fr', sortable: true, num: true },
    { key: 'spark', label: 'Trend', w: '1.1fr', sortable: false },
  ];
  const sorted = [...baskets].sort((a, b) => (a[sortKey] - b[sortKey]) * dir);
  const setSort = (k) => { if (k === sortKey) setDir(d => -d); else { setSortKey(k); setDir(-1); } };

  return (
    <div className="page" style={{ padding: '32px 32px 64px', maxWidth: 1180, margin: '0 auto', animation: 'fadeIn .35s ease .06s forwards' }}>
      <PageHead n="— LEADERBOARD" title="Top baskets" sub="Every basket on the platform, ranked live."
        right={<div style={{ display: 'inline-flex', background: 'var(--surface-2)', borderRadius: 10, padding: 3, border: '1px solid var(--line)' }}>
          {[['perf7d', '7D'], ['perf30d', '30D'], ['perfAll', 'All']].map(([k, l]) => (
            <button key={k} onClick={() => { setTf(k); setSortKey(k); setDir(-1); }} style={{ padding: '7px 15px', borderRadius: 8, border: 'none', cursor: 'pointer', fontFamily: 'var(--mono)', fontSize: 12.5, fontWeight: 600, background: tf === k ? 'var(--text)' : 'transparent', color: tf === k ? 'var(--bg)' : 'var(--text-2)', transition: 'all .15s' }}>{l}</button>
          ))}
        </div>} />

      <Card pad={0} style={{ overflow: 'hidden' }}>
        {/* header row */}
        {!isMobile && (
          <div style={{ display: 'grid', gridTemplateColumns: cols.map(c => c.w).join(' '), gap: 14, padding: '14px 22px', borderBottom: '1px solid var(--line-2)', background: 'var(--bg-2)' }}>
            {cols.map(c => (
              <button key={c.key} disabled={!c.sortable} onClick={() => c.sortable && setSort(c.key)}
                className="eyebrow"
                style={{ background: 'none', border: 'none', cursor: c.sortable ? 'pointer' : 'default', textAlign: c.num ? 'right' : 'left', justifyContent: c.num ? 'flex-end' : 'flex-start', display: 'flex', alignItems: 'center', gap: 5, color: sortKey === c.key ? 'var(--accent-ink)' : 'var(--text-3)', padding: 0, fontFamily: 'var(--mono)' }}>
                {c.label}{sortKey === c.key && <span>{dir === -1 ? '↓' : '↑'}</span>}
              </button>
            ))}
          </div>
        )}
        {/* rows */}
        {loading && [...Array(6)].map((_, i) => (
          <div key={'sk' + i} style={{ display: 'grid', gridTemplateColumns: isMobile ? '1fr' : cols.map(c => c.w).join(' '), gap: 14, padding: '16px 22px', borderBottom: i < 5 ? '1px solid var(--line)' : 'none', alignItems: 'center' }}>
            {isMobile ? <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}><Skel w={60} h={26} r={99} /><Skel w="50%" h={16} /><span style={{ marginLeft: 'auto' }}><Skel w={60} h={18} /></span></div>
              : <><Skel w={16} h={14} /><div style={{ display: 'flex', alignItems: 'center', gap: 12 }}><Skel w={80} h={28} r={99} /><Skel w={120} h={16} /></div><Skel w={60} h={16} style={{ justifySelf: 'end' }} /><Skel w={54} h={16} style={{ justifySelf: 'end' }} /><Skel w={48} h={16} style={{ justifySelf: 'end' }} /><Skel w={100} h={26} style={{ justifySelf: 'end' }} /></>}
          </div>
        ))}
        {!loading && sorted.map((b, i) => {
          const v = b[tf];
          if (isMobile) {
            return (
              <div key={b.id} onClick={() => onOpenBasket(b.id)} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', borderBottom: i < sorted.length - 1 ? '1px solid var(--line)' : 'none', cursor: 'pointer' }}>
                <span className="data" style={{ fontSize: 13, color: 'var(--text-3)', width: 20 }}>{i + 1}</span>
                <TokenStack tokens={b.tokens} size={26} max={3} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 14 }}>{b.name}</div>
                  <div className="data" style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{fmtCompact(b.aum)} · {b.copiers.toLocaleString()}</div>
                </div>
                <div className="data" style={{ fontSize: 16, fontWeight: 700, color: v >= 0 ? 'var(--accent-ink)' : 'var(--danger)' }}>{fmtPct(v)}</div>
              </div>
            );
          }
          return (
            <div key={b.id} onClick={() => onOpenBasket(b.id)} className="lb-row"
              style={{ display: 'grid', gridTemplateColumns: cols.map(c => c.w).join(' '), gap: 14, padding: '14px 22px', borderBottom: i < sorted.length - 1 ? '1px solid var(--line)' : 'none', alignItems: 'center', cursor: 'pointer', transition: 'background .14s' }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--surface-2)'}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <span className="data" style={{ fontSize: 14, fontWeight: 700, color: i < 3 ? 'var(--accent-ink)' : 'var(--text-3)' }}>{i + 1}</span>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, minWidth: 0 }}>
                <TokenStack tokens={b.tokens} size={28} max={4} />
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 14.5 }}>{b.name}</div>
                  <button onClick={(e) => { e.stopPropagation(); onOpenKol(b.kol.handle); }} className="data" style={{ background: 'none', border: 'none', padding: 0, fontSize: 11.5, color: 'var(--text-3)', cursor: 'pointer' }}>{b.kol.x}</button>
                </div>
              </div>
              <div className="data" style={{ textAlign: 'right', fontSize: 16, fontWeight: 700, color: v >= 0 ? 'var(--accent-ink)' : 'var(--danger)' }}>{fmtPct(v)}</div>
              <div className="data" style={{ textAlign: 'right', fontSize: 14, fontWeight: 600 }}>{fmtCompact(b.aum)}</div>
              <div className="data" style={{ textAlign: 'right', fontSize: 14, fontWeight: 600 }}>{b.copiers.toLocaleString()}</div>
              <div style={{ display: 'flex', justifyContent: 'flex-end' }}><Sparkline data={b.spark} w={110} h={32} sw={2} color={v >= 0 ? 'var(--accent-ink)' : 'var(--danger)'} /></div>
            </div>
          );
        })}
      </Card>
    </div>
  );
}

Object.assign(window, { CommandPalette, KolProfile, Leaderboard });
