/* ============================================================
   basket.fun — app root + router
   ============================================================ */
function shortWalletText(value) {
  const s = String(value || '');
  return s.length > 18 ? s.slice(0, 8) + '...' + s.slice(-6) : s;
}

function walletBalanceItems(dataState) {
  const balances = dataState && dataState.walletBalances;
  return balances && Array.isArray(balances.items) ? balances.items : [];
}

function WalletBalanceList({ dataState = {} }) {
  const items = walletBalanceItems(dataState);
  if (!items.length) return null;
  return (
    <div style={{ marginBottom: 16, borderRadius: 14, border: '1px solid var(--line)', background: 'var(--bg-2)', padding: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10, marginBottom: 8 }}>
        <div className="eyebrow">Linked balances</div>
        <div className="tnum" style={{ fontSize: 12.5, color: 'var(--accent-ink)', fontWeight: 750 }}>
          {fmtUsd(Number(dataState.walletUsdcBalance || 0))} USDC
        </div>
      </div>
      <div style={{ display: 'grid', gap: 8 }}>
        {items.map(item => {
          const native = item.balances && item.balances.native;
          const usdc = item.balances && item.balances.usdc;
          return (
            <div key={item.id || item.address} style={{ display: 'grid', gap: 7, padding: '10px 11px', borderRadius: 12, border: '1px solid var(--line)', background: 'var(--surface)' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <WalletBrandIcon id={item.wallet_type} label={item.wallet_type} chain={item.chain === 'base' ? 'base' : 'solana'} size={24} />
                <ChainBadge chain={item.chain === 'base' ? 'base' : 'sol'} size="sm" />
                <span style={{ flex: 1, minWidth: 0, fontFamily: 'var(--mono)', fontSize: 12.5, color: 'var(--text-2)' }}>{shortWalletText(item.address)}</span>
                <span style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{item.wallet_type || 'wallet'}</span>
              </div>
              {item.error ? (
                <div style={{ display: 'flex', alignItems: 'flex-start', gap: 7, fontSize: 12, color: 'var(--warning)', lineHeight: 1.35 }}>
                  <Icon name="info" size={13} color="currentColor" style={{ marginTop: 1, flexShrink: 0 }} />
                  <span style={{ wordBreak: 'break-word' }}>{item.error}</span>
                </div>
              ) : (
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
                  <div>
                    <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 2 }}>{native ? native.symbol : 'Native'}</div>
                    <div className="tnum" style={{ fontSize: 13, fontWeight: 700 }}>{native ? Number(native.amount || 0).toLocaleString(undefined, { maximumFractionDigits: 6 }) : '--'}</div>
                  </div>
                  <div style={{ textAlign: 'right' }}>
                    <div style={{ fontSize: 11, color: 'var(--text-3)', marginBottom: 2 }}>USDC</div>
                    <div className="tnum" style={{ fontSize: 13, fontWeight: 700 }}>{usdc ? fmtUsd(Number(usdc.amount || 0)) : '--'}</div>
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function WalletProviderPicker({ open, providers = [], dataState = {}, auth, workingProvider, onSelect, onDisconnect, onClose }) {
  if (!open) return null;
  const localDev = dataState && dataState.config && dataState.config.localDevAuthEnabled;
  const connected = auth && auth.connected;
  const currentWallet = connected && auth.wallet ? auth.wallet : null;
  const grouped = providers.reduce((acc, row) => {
    const key = row.chain === 'base' ? 'Base' : 'Solana';
    acc[key] = acc[key] || [];
    acc[key].push(row);
    return acc;
  }, {});
  const groupNames = Object.keys(grouped);
  return (
    <Portal>
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, zIndex: 110, background: 'rgba(0,0,0,0.38)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 18,
      }}>
        <div onClick={e => e.stopPropagation()} style={{
          width: 'min(500px, 100%)', borderRadius: 18, border: '1px solid var(--line-2)',
          background: 'var(--surface)', boxShadow: 'var(--shadow-lg)', padding: 20,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>
            <div style={{ width: 38, height: 38, borderRadius: 12, background: 'var(--accent-wash)', color: 'var(--accent-ink)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Icon name="wallet" size={19} color="currentColor" />
            </div>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 17, fontWeight: 800 }}>{connected ? 'Wallet session' : 'Connect wallet'}</div>
              <div style={{ fontSize: 12.5, color: 'var(--text-3)', marginTop: 2 }}>{connected ? 'Switch wallets or disconnect the current session.' : 'Choose a detected Solana or Base wallet.'}</div>
            </div>
            <button onClick={onClose} aria-label="Close" style={{ width: 34, height: 34, borderRadius: 10, border: '1px solid var(--line)', background: 'var(--surface-2)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <Icon name="x" size={14} color="var(--text-3)" />
            </button>
          </div>

          {connected && (
            <div style={{
              display: 'flex', alignItems: 'center', gap: 11, flexWrap: 'wrap',
              padding: 12, marginBottom: 14, borderRadius: 14,
              border: '1px solid rgba(163,255,91,0.28)', background: 'var(--accent-wash)',
            }}>
              <WalletBrandIcon
                id={currentWallet && currentWallet.label}
                label={currentWallet && currentWallet.label}
                chain={currentWallet && currentWallet.chain}
                size={34}
              />
              <div style={{ minWidth: 0, flex: '1 1 170px' }}>
                <div style={{ fontSize: 13.5, fontWeight: 800, color: 'var(--accent-ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {(currentWallet && currentWallet.label) || 'Connected wallet'}
                </div>
                <div style={{ marginTop: 2, fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--text-2)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {(currentWallet && (currentWallet.short || currentWallet.address)) || 'Session active'}
                </div>
              </div>
              <button onClick={onDisconnect} disabled={Boolean(workingProvider)} style={{
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 7,
                minHeight: 34, padding: '8px 12px', borderRadius: 10,
                border: '1px solid rgba(255,91,91,0.28)', background: 'rgba(255,91,91,0.08)',
                color: 'var(--danger)', fontFamily: 'var(--font)', fontSize: 12.5, fontWeight: 800,
                cursor: workingProvider ? 'default' : 'pointer',
              }}>
                Disconnect wallet
              </button>
            </div>
          )}

          <WalletBalanceList dataState={dataState} />

          {groupNames.length > 0 ? groupNames.map(group => (
            <div key={group} style={{ marginTop: 12 }}>
              <div className="eyebrow" style={{ marginBottom: 8 }}>{group}</div>
              <div style={{ display: 'grid', gap: 8 }}>
                {grouped[group].map(provider => {
                  const busy = workingProvider === provider.id;
                  return (
                    <button key={provider.id} onClick={() => onSelect(provider.id)} disabled={Boolean(workingProvider)} style={{
                      display: 'flex', alignItems: 'center', gap: 10, width: '100%', padding: '12px 13px',
                      borderRadius: 12, border: '1px solid var(--line)', background: 'var(--bg-2)',
                      cursor: workingProvider ? 'default' : 'pointer', color: 'var(--text)', fontFamily: 'var(--font)',
                      opacity: workingProvider && !busy ? 0.55 : 1,
                    }}>
                      <WalletBrandIcon id={provider.id} label={provider.label} chain={provider.chain} size={30} />
                      <span style={{ flex: 1, minWidth: 0, textAlign: 'left', fontSize: 13.5, fontWeight: 750, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{provider.label}</span>
                      <ChainBadge chain={provider.chain === 'base' ? 'base' : 'sol'} size="sm" />
                      {busy && <span style={{ fontSize: 12, color: 'var(--text-3)' }}>Signing...</span>}
                    </button>
                  );
                })}
              </div>
            </div>
          )) : (
            <div style={{ padding: '14px 12px', borderRadius: 12, background: 'var(--bg-2)', border: '1px solid var(--line)', color: 'var(--text-2)', fontSize: 13, lineHeight: 1.45 }}>
              No injected wallet was detected in this browser. Install Phantom, OKX Wallet, MetaMask, Coinbase Wallet, Rabby, Solflare, or Backpack, then reload.
            </div>
          )}

          {groupNames.length === 0 && localDev && (
            <Btn full size="md" icon="wallet" onClick={() => onSelect(null)} disabled={Boolean(workingProvider)} style={{ marginTop: 12 }}>
              {workingProvider === 'local-dev' ? 'Connecting...' : 'Use local dev wallet'}
            </Btn>
          )}
        </div>
      </div>
    </Portal>
  );
}

function LiveLoadingScreen({ dataState = {} }) {
  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: 'var(--accent-ink)', marginBottom: 14 }}>
          Live marketplace
        </div>
        <h1 className="display" style={{ margin: 0, fontSize: 'clamp(32px, 4vw, 52px)', fontWeight: 900, lineHeight: 1 }}>
          Loading baskets...
        </h1>
        <p style={{ margin: '18px 0 0', color: 'var(--text-2)', fontSize: 16, lineHeight: 1.55, maxWidth: 620 }}>
          {dataState.message || 'Connecting to basket-fund...'}
        </p>
      </section>
    </div>
  );
}

function App() {
  const authCallback = window.BasketAPI ? window.BasketAPI.consumeAuthFromLocation() : { consumed: false };
  const params = new URLSearchParams(location.search);
  const initView = params.get('view') || 'explore';
  const initBasket = params.get('basket');
  const [nav, setNav] = useState(initBasket ? { view: 'explore', basketId: initBasket } : { view: initView });
  const [copy, setCopy] = useState(params.get('copy') || null); // basketId being copied
  const [searchSheet, setSearchSheet] = useState(false);
  const [cmdk, setCmdk] = useState(false);
  const [dataState, setDataState] = useState(() => ({
    mode: (window.DB && window.DB.api && window.DB.api.mode) || 'loading',
    online: false,
    message: 'Connecting to backend...',
    apiBase: window.BasketAPI ? window.BasketAPI.getApiBase() : '',
  }));
  const [auth, setAuth] = useState(() => window.BasketAPI ? window.BasketAPI.authState() : { connected: false, token: '' });
  const [notice, setNotice] = useState(() => authCallback && authCallback.error ? authCallback.error : null);
  const [walletPickerOpen, setWalletPickerOpen] = useState(false);
  const [walletProviders, setWalletProviders] = useState([]);
  const [workingProvider, setWorkingProvider] = useState('');

  const go = (v, extra) => { setNav({ view: v, ...extra }); window.scrollTo(0, 0); };
  const currentDb = window.DB || {};
  const currentBaskets = currentDb.baskets || [];
  const isLiveLoading = dataState.mode === 'loading' && currentBaskets.length === 0;
  const basketIds = currentBaskets.map(b => b.id);
  const openKol = (handle) => go('kolprofile', { kolHandle: handle });
  const refreshAuth = () => setAuth(window.BasketAPI ? window.BasketAPI.authState() : { connected: false, token: '' });
  const applyData = (db) => {
    window.DB = db;
    setDataState(db.api || { mode: 'demo', online: false, message: 'Demo data loaded.' });
    refreshAuth();
    return db;
  };
  const reloadData = async () => {
    if (!window.BasketAPI) return window.DB;
    return applyData(await window.BasketAPI.safeLoadData());
  };

  useEffect(() => {
    if (!notice) return;
    const timer = setTimeout(() => setNotice(null), 5200);
    return () => clearTimeout(timer);
  }, [notice]);

  useEffect(() => {
    if (!window.BasketAPI) return;
    let cancelled = false;
    setDataState(s => ({ ...s, mode: 'loading', message: 'Connecting to basket-fund...' }));
    window.BasketAPI.safeLoadData().then((db) => {
      if (cancelled) return;
      applyData(db);
    });
    return () => { cancelled = true; };
  }, []);

  const openWalletPicker = () => {
    if (!window.BasketAPI) return;
    try {
      setWalletProviders(window.BasketAPI.discoverWallets());
      setWalletPickerOpen(true);
      if (window.BasketAPI.refreshWalletProviders) {
        window.BasketAPI.refreshWalletProviders().then(setWalletProviders).catch(() => null);
      }
      if (auth && auth.connected) {
        reloadData().catch(() => null);
      }
    } catch (e) {
      setNotice(e.message || 'Could not inspect browser wallets.');
    }
  };

  const connectWallet = async (providerId) => {
    if (!window.BasketAPI) return;
    const busyKey = providerId || 'local-dev';
    setWorkingProvider(busyKey);
    try {
      await window.BasketAPI.connectWalletSession(providerId);
      refreshAuth();
      await reloadData();
      setWalletPickerOpen(false);
    } catch (e) {
      setNotice(e.message || 'Could not connect wallet.');
    } finally {
      setWorkingProvider('');
    }
  };

  const connectX = async () => {
    if (!window.BasketAPI) return;
    try {
      await window.BasketAPI.connectTwitterSession();
      refreshAuth();
      await reloadData();
    } catch (e) {
      setNotice(e.message || 'X OAuth is not configured on the backend yet.');
    }
  };

  const logout = () => {
    if (window.BasketAPI) window.BasketAPI.setToken('');
    setWalletPickerOpen(false);
    setWorkingProvider('');
    refreshAuth();
    setNotice('Wallet disconnected.');
    reloadData().catch(() => null);
  };

  // ⌘K / Ctrl-K to open command palette
  useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && (e.key === 'k' || e.key === 'K')) { e.preventDefault(); setCmdk(o => !o); }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  useEffect(() => {
    const onNavigate = (event) => {
      const detail = event && event.detail ? event.detail : {};
      if (detail.view) go(detail.view, detail);
    };
    window.addEventListener('basket:navigate', onNavigate);
    return () => window.removeEventListener('basket:navigate', onNavigate);
  }, []);

  return (
    <>
      <AppShell
        nav={nav}
        setNav={setNav}
        onSearch={() => setSearchSheet(true)}
        onCmdk={() => setCmdk(true)}
        dataState={dataState}
        activity={(window.DB && window.DB.activity) || []}
        auth={auth}
        onConnectX={openWalletPicker}
        onLogout={logout}
      >
        {isLiveLoading ? (
          <LiveLoadingScreen dataState={dataState} />
        ) : (
          <>
            {nav.view === 'explore' && !nav.basketId && (
              <ExploreScreen onOpen={(id) => go('explore', { basketId: id })} sheetOpen={searchSheet} setSheetOpen={setSearchSheet} />
            )}
            {nav.view === 'explore' && nav.basketId && (
              <BasketDetail basketId={nav.basketId} order={basketIds}
                onNavigate={(id) => go('explore', { basketId: id })}
                onBack={() => go('explore')} onCopy={(id) => setCopy(id)} onOpenKol={openKol} />
            )}
            {nav.view === 'leaderboard' && (
              <Leaderboard onOpenBasket={(id) => go('explore', { basketId: id })} onOpenKol={openKol} />
            )}
            {nav.view === 'kolprofile' && (
              <KolProfile handle={nav.kolHandle} onBack={() => go('explore')} onOpenBasket={(id) => go('explore', { basketId: id })} onCopy={(id) => setCopy(id)} />
            )}
            {nav.view === 'portfolio' && (
              <PortfolioScreen
                onOpen={(id) => go('explore', { basketId: id })}
                onCopyMore={(id) => setCopy(id)}
                auth={auth}
                dataState={dataState}
                onConnectWallet={openWalletPicker}
              />
            )}
            {nav.view === 'kol' && (
              <KolStudio
                auth={auth}
                dataState={dataState}
                onConnectWallet={openWalletPicker}
                onConnectX={connectX}
                onDisconnect={logout}
                onDataReload={reloadData}
                onAuthChanged={refreshAuth}
              />
            )}
            {nav.view === 'activity' && <ActivityScreen />}
          </>
        )}
      </AppShell>

      <CommandPalette open={cmdk} onClose={() => setCmdk(false)}
        onNav={(v) => go(v)} onOpenBasket={(id) => go('explore', { basketId: id })} onOpenKol={openKol} />

      {copy && !isLiveLoading && (
        <Portal>
          <CopyModal
            basketId={copy}
            auth={auth}
            dataState={dataState}
            onConnectX={openWalletPicker}
            onAuthChanged={refreshAuth}
            onClose={() => setCopy(null)}
            onViewPosition={() => { setCopy(null); go('portfolio'); }}
          />
        </Portal>
      )}

      {notice && (
        <Portal>
          <div style={{
            position: 'fixed', left: '50%', bottom: 24, transform: 'translateX(-50%)', zIndex: 100,
            background: 'var(--surface)', color: 'var(--text)', border: '1px solid var(--line-2)',
            borderRadius: 14, padding: '13px 16px', boxShadow: 'var(--shadow-lg)',
            maxWidth: 480, fontSize: 13, lineHeight: 1.45,
          }}>{notice}</div>
        </Portal>
      )}

      <WalletProviderPicker
        open={walletPickerOpen}
        providers={walletProviders}
        dataState={dataState}
        auth={auth}
        workingProvider={workingProvider}
        onSelect={connectWallet}
        onDisconnect={logout}
        onClose={() => !workingProvider && setWalletPickerOpen(false)}
      />
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
