/* ============================================================
   CADENCE — Shared components
   window.UI = { Cover, Sidebar, TopBar, MobileTabs, SongCard, Stat,
                 Delta, NowPlaying, ToastHost, Logo helpers }
   ============================================================ */
(function () {
  const { useState, useEffect, useRef } = React;
  const I = window.Icon;
  const F = window.CAD.fmt;

  function initialsOf(name) {
    const parts = String(name || 'You').trim().split(/\s+/).filter(Boolean);
    if (parts.length === 0) return 'You';
    if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
    return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
  }

  function signOut() {
    window.CAD_API.logout()
      .catch(() => {})
      .then(() => window.location.reload());
  }

  // album cover placeholder (gradient + grain + waveform hint)
  function Cover({ grad, label, size, radius, playable, playing, onPlay, style }) {
    return (
      <div className="cover" style={{ width: size, height: size, borderRadius: radius, ...style }}>
        <div className="cv-grad" style={{ background: grad }} />
        <div className="cv-noise" />
        {playing && (
          <div style={{ position: 'absolute', inset: 0, zIndex: 3, display: 'grid', placeItems: 'center' }}>
            <div className="eq" style={{ height: '34%' }}><i></i><i></i><i></i><i></i></div>
          </div>
        )}
      </div>
    );
  }

  function Delta({ value, size }) {
    const up = value >= 0;
    return (
      <span className={'delta ' + (up ? 'up' : 'down')} style={size ? { fontSize: size } : null}>
        {up ? <I.up /> : <I.down />}{up ? '+' : ''}{value.toFixed(1)}%
      </span>
    );
  }

  function Stat({ k, v, sub, accent }) {
    return (
      <div className="stat">
        <div className="k">{k}</div>
        <div className="v" style={accent ? { color: accent } : null}>{v}</div>
        {sub && <div style={{ marginTop: 4 }}>{sub}</div>}
      </div>
    );
  }

  const NAV = [
    { id: 'discover', label: 'Discover', icon: 'discover' },
    { id: 'portfolio', label: 'Portfolio', icon: 'portfolio' },
    { id: 'artist', label: 'Artist Studio', icon: 'artist' },
  ];

  function Sidebar({ view, go }) {
    const p = window.CAD.portfolio;
    const { addFunds } = window.useCad();

    const onAddFunds = async () => {
      const raw = window.prompt('Add funds to your wallet (USD):', '100');
      if (raw == null) return;
      const amt = Number(raw);
      if (!Number.isFinite(amt) || amt <= 0) {
        window.toast({ kind: 'sell', title: 'Invalid amount', desc: 'Enter a positive dollar amount.' });
        return;
      }
      try {
        await addFunds(amt);
        window.toast({ title: 'Funds added', desc: `${F.money(amt, 2)} added to your wallet.` });
      } catch (error) {
        const desc = error?.message === 'amount_too_large' ? 'That amount is too large.' : 'Could not add funds.';
        window.toast({ kind: 'sell', title: 'Top-up failed', desc });
      }
    };

    return (
      <aside className="sidebar">
        <window.Wordmark />
        <div className="nav-group-label">Platform</div>
        {NAV.slice(0, 2).map((n) => (
          <div key={n.id} className={'nav-item' + (view === n.id ? ' active' : '')} onClick={() => go(n.id)}>
            {React.createElement(I[n.icon])}<span>{n.label}</span>
            {n.id === 'discover' && <span className="nav-badge">{(window.CAD.songs || []).length}</span>}
          </div>
        ))}
        <div className="nav-group-label">Create</div>
        <div className={'nav-item' + (view === 'artist' ? ' active' : '')} onClick={() => go('artist')}>
          <I.artist /><span>Artist Studio</span>
        </div>
        <div className={'nav-item' + (view === 'upload' ? ' active' : '')} onClick={() => go('upload')}>
          <I.upload /><span>Upload Music</span>
        </div>

        <div className="sidebar-foot">
          <div className="wallet-card">
            <div className="row between">
              <span className="lbl">Wallet balance</span>
              <I.wallet style={{ width: 15, height: 15, color: 'var(--text-mute)' }} />
            </div>
            <div className="bal">{F.money(p.balance, 2)}</div>
            <div className="row" style={{ gap: 8, marginTop: 11 }}>
              <button className="btn btn-ghost" style={{ flex: 1, padding: '8px', fontSize: 13 }} onClick={onAddFunds}>
                <I.plus style={{ width: 14, height: 14 }} />Add funds
              </button>
              <button className="btn btn-ghost" style={{ flex: 1, padding: '8px', fontSize: 13 }} onClick={signOut} title="Sign out">
                <I.x style={{ width: 14, height: 14 }} />Sign out
              </button>
            </div>
          </div>
        </div>
      </aside>
    );
  }

  function MobileTabs({ view, go }) {
    return (
      <nav className="mobile-tabbar">
        {NAV.map((n) => (
          <div key={n.id} className={'mt' + (view === n.id ? ' active' : '')} onClick={() => go(n.id)}>
            {React.createElement(I[n.icon])}<span>{n.label}</span>
          </div>
        ))}
      </nav>
    );
  }

  function TopBar({ go, onSearch, query, marketDelta, onMenu }) {
    const [menuOpen, setMenuOpen] = useState(false);
    const menuRef = useRef(null);
    const user = window.CAD.currentUser || {};

    useEffect(() => {
      if (!menuOpen) return;
      const onDoc = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false); };
      document.addEventListener('mousedown', onDoc);
      return () => document.removeEventListener('mousedown', onDoc);
    }, [menuOpen]);

    return (
      <header className="topbar">
        <div className="search hide-xs">
          <I.discover />
          <input value={query} onChange={(e) => onSearch(e.target.value)} placeholder="Search songs, artists, tickers…" />
        </div>
        <div className="topbar-spacer" />
        <div className="ticker-pill hide-sm">
          <span className="dot"></span>
          <span className="muted">CAD Index</span>
          <span style={{ color: marketDelta >= 0 ? 'var(--green)' : 'var(--red)' }}>
            {marketDelta >= 0 ? '+' : ''}{marketDelta.toFixed(2)}%
          </span>
        </div>
        <div className="icon-btn hide-sm" title="Activity"><I.bell /><span className="dotnote"></span></div>
        <div ref={menuRef} style={{ position: 'relative' }}>
          <div className="avatar" title={user.displayName || 'Account'} style={{ cursor: 'pointer', ...(user.avatarColor ? { background: user.avatarColor } : {}) }} onClick={() => setMenuOpen((o) => !o)}>{initialsOf(user.displayName)}</div>
          {menuOpen && (
            <div className="panel" style={{ position: 'absolute', right: 0, top: 'calc(100% + 8px)', width: 210, padding: 8, zIndex: 60 }}>
              <div style={{ padding: '6px 10px 8px' }}>
                <div style={{ fontWeight: 700, fontSize: 13 }}>{user.displayName || 'You'}</div>
                <div className="muted" style={{ fontSize: 11.5 }}>@{user.handle || user.username || ''}</div>
              </div>
              <div style={{ height: 1, background: 'var(--border-soft)', margin: '2px 0 8px' }} />
              <button className="btn btn-ghost btn-block" style={{ justifyContent: 'flex-start', marginBottom: 6 }} onClick={() => { setMenuOpen(false); go('profile'); }}><I.settings style={{ width: 14 }} />Edit profile</button>
              <button className="btn btn-ghost btn-block" style={{ justifyContent: 'flex-start', marginBottom: 6 }} onClick={() => { setMenuOpen(false); go('portfolio'); }}>View portfolio</button>
              <button className="btn btn-ghost btn-block" style={{ justifyContent: 'flex-start', color: 'var(--red, #f87171)' }} onClick={signOut}><I.x style={{ width: 14 }} />Sign out</button>
            </div>
          )}
        </div>
      </header>
    );
  }

  // Song card for marketplace grid
  function SongCard({ song, onOpen, onPlay, playingId, watch, onWatch, delay }) {
    const playing = playingId === song.id;
    return (
      <div className="song-card fade-up" style={{ animationDelay: (delay || 0) + 'ms' }} onClick={() => onOpen(song.id)}>
        <div className="topline">
          <Cover grad={song.coverGrad} size={60} radius={10} playing={playing} />
          <div className="meta">
            <div className="row between" style={{ alignItems: 'flex-start' }}>
              <div style={{ minWidth: 0 }}>
                <div className="title">{song.title}</div>
                <div className="artist">{song.artist}</div>
              </div>
              <span className="num muted" style={{ fontSize: 11, flex: 'none' }}>{song.genreLabel.split(' ')[0]}</span>
            </div>
            <div className="price-row">
              <span className="price">{F.money(song.price, 2)}</span>
              <window.UI.Delta value={song.change} />
            </div>
          </div>
        </div>
        <div className="sparkbox">
          <window.Charts.Sparkline data={song.series} up={song.change >= 0} />
        </div>
        <div className="footrow">
          <span>Vol <span className="num">{F.compact(song.vol24)}</span></span>
          <span>Mcap <span className="num">{F.compact(song.mcap)}</span></span>
          <span><span className="num">{song.available.toFixed(1)}%</span> open</span>
        </div>
        <button className="play-fab" onClick={(e) => { e.stopPropagation(); onPlay(song.id); }}>
          {playing ? <I.pause /> : <I.play />}
        </button>
      </div>
    );
  }

  // bottom now-playing bar
  function NowPlaying({ song, playing, onToggle, progress, elapsed, total }) {
    if (!song) return null;
    return (
      <div className={'nowplaying' + (song ? ' show' : '')}>
        <Cover grad={song.coverGrad} size={42} radius={8} playing={playing} />
        <div style={{ minWidth: 0 }}>
          <div style={{ fontWeight: 700, fontSize: 13.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{song.title}</div>
          <div style={{ fontSize: 12, color: 'var(--text-mute)' }}>{song.artist}</div>
        </div>
        <div className="row" style={{ gap: 6, marginLeft: 10 }}>
          <button className="icon-btn hide-sm" style={{ width: 34, height: 34, background: 'transparent', border: 0 }}><I.skipback style={{ width: 16 }} /></button>
          <button className="icon-btn" style={{ width: 38, height: 38, background: 'var(--text)', color: '#0e1116', border: 0 }} onClick={onToggle}>
            {playing ? <I.pause /> : <I.play />}
          </button>
          <button className="icon-btn hide-sm" style={{ width: 34, height: 34, background: 'transparent', border: 0 }}><I.skipfwd style={{ width: 16 }} /></button>
        </div>
        <div className="grow row gap8 hide-sm" style={{ maxWidth: 420 }}>
          <span className="num muted" style={{ fontSize: 11 }}>{elapsed || '0:00'}</span>
          <div className="grow" style={{ height: 4, borderRadius: 999, background: 'var(--surface-3)', overflow: 'hidden' }}>
            <div style={{ width: progress + '%', height: '100%', background: 'linear-gradient(90deg,var(--blue),var(--green))' }} />
          </div>
          <span className="num muted" style={{ fontSize: 11 }}>{total || song.length || '—'}</span>
        </div>
        <div className="row gap8" style={{ marginLeft: 'auto' }}>
          <div className="eq hide-sm"><i></i><i></i><i></i><i></i></div>
          <span className="num pos hide-xs" style={{ fontSize: 12 }}>+{(song.yield).toFixed(1)}% yield</span>
        </div>
      </div>
    );
  }

  // Toast host (imperative via window.toast)
  function ToastHost() {
    const [toasts, setToasts] = useState([]);
    useEffect(() => {
      window.toast = (t) => {
        const id = Math.random().toString(36).slice(2);
        setToasts((x) => [...x, { ...t, id }]);
        setTimeout(() => setToasts((x) => x.filter((y) => y.id !== id)), t.duration || 3800);
      };
    }, []);
    return (
      <div className="toast-wrap">
        {toasts.map((t) => (
          <div className="toast" key={t.id}>
            <div className="ic" style={{ background: t.kind === 'sell' ? 'var(--red-tint)' : 'var(--green-tint)', color: t.kind === 'sell' ? 'var(--red-bright)' : 'var(--green-bright)' }}>
              {t.kind === 'sell' ? <I.arrowUp style={{ transform: 'rotate(180deg)' }} /> : <I.check />}
            </div>
            <div style={{ flex: 1 }}>
              <div className="t">{t.title}</div>
              <div className="d">{t.desc}</div>
            </div>
          </div>
        ))}
      </div>
    );
  }

  window.UI = { Cover, Delta, Stat, Sidebar, MobileTabs, TopBar, SongCard, NowPlaying, ToastHost, NAV };
})();
