/* ============================================================
   CADENCE — Song Detail / Trading page (hero)
   window.SongDetail
   ============================================================ */
(function () {
  const { useState, useEffect, useRef, useMemo } = React;
  const I = window.Icon;
  const requestJson = window.CAD_API.requestJson;
  const F = window.CAD.fmt;
  const C = window.Charts;

  const TIMEFRAMES = ['1H', '24H', '1W', '1M', 'ALL'];

  function SongDetail({ song, balance, owned, onTrade, onBuy, onBuyAlbum, playSong, playingId, progress, audioTime, audioDur, tradeVariant, chartMode, go, watch, onWatch }) {
    const [tf, setTf] = useState('1W');
    const [livePrice, setLivePrice] = useState(song.price);
    const [liveSeries, setLiveSeries] = useState(song.series);
    const [flash, setFlash] = useState(null);
    const [buying, setBuying] = useState(false);
    const [albumBuying, setAlbumBuying] = useState(false);
    const salePrice = song.salePrice != null ? Number(song.salePrice) : 0;

    const release = song.release || null;
    const individualOn = !release || release.sellIndividually !== false;
    const albumPrice = release && release.bundlePrice != null ? Number(release.bundlePrice) : null;

    const doBuy = async () => {
      if (buying || !song.buyable) return;
      setBuying(true);
      try {
        await onBuy();
      } finally {
        setBuying(false);
      }
    };

    const doBuyAlbum = async () => {
      if (albumBuying || !release) return;
      setAlbumBuying(true);
      try {
        await onBuyAlbum(release.id);
      } finally {
        setAlbumBuying(false);
      }
    };

    // reset when song changes
    useEffect(() => { setLivePrice(song.price); setLiveSeries(song.series); }, [song.id, song.price, song.series]);

    // live updates
    useEffect(() => {
      let cancelled = false;

      const refresh = async () => {
        try {
          const data = await requestJson(`/api/songs/${song.id}/live`);
          if (cancelled) return;
          setLivePrice((current) => {
            if (data.price !== current) {
              setFlash(data.price >= current ? 'up' : 'down');
              setTimeout(() => setFlash(null), 600);
            }
            return data.price;
          });
          setLiveSeries(data.series);
        } catch (error) {
          if (!cancelled) {
            setFlash(null);
          }
        }
      };

      refresh();
      const iv = setInterval(() => {
        refresh();
      }, 2600);
      return () => {
        cancelled = true;
        clearInterval(iv);
      };
    }, [song.id]);

    const playing = playingId === song.id;
    const hasDur = playing && audioDur > 0;
    const miniElapsed = hasDur ? F.time(audioTime) : '0:00';
    const miniTotal = hasDur ? F.time(audioDur) : (song.length || '—');
    const miniPct = playing ? (progress || 0) : 0;
    const liveChange = +(((livePrice - song.series[0]) / song.series[0]) * 100).toFixed(2);
    const isWatched = watch.includes(song.id);

    // timeframe slice
    const shown = useMemo(() => {
      const map = { '1H': 12, '24H': 24, '1W': 40, '1M': 60, 'ALL': 60 };
      return liveSeries.slice(-map[tf]);
    }, [liveSeries, tf]);

    // Ownership of the whole song (sums to 100%). The public stake is publicPct,
    // split into the portion investors have bought vs. what's still available.
    const availOfSong = Math.round(song.publicPct * (song.available / 100) * 10) / 10;
    const investorsOfSong = Math.round((song.publicPct - availOfSong) * 10) / 10;
    const ownSegments = [
      { label: 'Artist holds', value: song.artistPct, color: 'oklch(0.70 0.165 252)' },
      { label: 'Investors hold', value: investorsOfSong, color: 'oklch(0.755 0.155 158)' },
      { label: 'Available', value: availOfSong, color: 'oklch(0.30 0.014 256)' },
    ];

    const stats = [
      ['Market cap', F.compact(song.mcap)],
      ['24h volume', F.compact(song.vol24)],
      ['Total revenue', F.compact(song.revenue)],
      ['Shareholders', song.holders.toLocaleString()],
      ['Total shares', song.totalShares.toLocaleString()],
      ['Available', song.sharesAvail.toLocaleString() + ' sh'],
    ];

    return (
      <div className="page">
        {/* breadcrumb / back */}
        <div className="row gap8" style={{ marginBottom: 18, fontSize: 13 }}>
          <span className="chip" onClick={() => go('discover')}><I.up style={{ width: 13, transform: 'rotate(-90deg)' }} />Genres</span>
          <span className="muted">/</span>
          <span className="dim">{song.genreLabel}</span>
          <span className="muted">/</span>
          <span style={{ fontWeight: 600 }}>{song.title}</span>
        </div>

        {/* header */}
        <div className="row between wrap fade-up" style={{ gap: 16, marginBottom: 22 }}>
          <div className="row gap16">
            <window.UI.Cover grad={song.coverGrad} size={84} radius={14} playing={playing} style={{ boxShadow: 'var(--shadow-1)' }} />
            <div>
              <div className="row gap8">
                <h1 className="page-title">{song.title}</h1>
                <span className="tag" style={{ alignSelf: 'center' }}>{song.genreLabel}</span>
              </div>
              <div className="dim" style={{ fontSize: 15, marginTop: 3 }}>{song.artist}</div>
              <div className="row gap16 mt12">
                <div className="num" style={{ fontSize: 30, fontWeight: 600, letterSpacing: '-0.03em' }}>
                  <span className={flash ? 'flash-' + flash : ''} style={{ padding: '2px 4px' }}>{F.money(livePrice, 2)}</span>
                </div>
                <window.UI.Delta value={liveChange} />
                <span className="live-dot" title="Live"></span>
              </div>
            </div>
          </div>
          <div className="row gap8">
            <button className="btn btn-ghost" onClick={() => playSong(song.id)}>{playing ? <I.pause style={{ width: 15 }} /> : <I.play style={{ width: 15 }} />}{playing ? 'Pause' : 'Preview'}</button>
            <button className="icon-btn" title="Watchlist" onClick={() => onWatch(song.id)} style={isWatched ? { color: 'var(--gold)', borderColor: 'oklch(0.82 0.11 88 / 0.4)' } : null}>
              {isWatched ? <I.starFill /> : <I.star />}
            </button>
          </div>
        </div>

        {/* 3-col grid */}
        <div className="song-detail-grid" style={{ display: 'grid', gridTemplateColumns: '288px 1fr 340px', gap: 18, alignItems: 'start' }}>

          {/* ---------- LEFT ---------- */}
          <div className="col gap16">
            <div className="panel">
              <window.UI.Cover grad={song.coverGrad} size="100%" radius={0} playing={playing} style={{ aspectRatio: '1', borderRadius: '15px 15px 0 0' }} />
              <div style={{ padding: 16 }}>
                {/* mini player */}
                <div className="row gap8" style={{ marginBottom: 12 }}>
                  <button className="icon-btn" style={{ width: 30, height: 30, background: 'transparent', border: 0, color: 'var(--text-mute)' }}><I.skipback style={{ width: 15 }} /></button>
                  <button className="icon-btn" style={{ width: 44, height: 44, background: 'var(--text)', color: '#0e1116', border: 0 }} onClick={() => playSong(song.id)}>{playing ? <I.pause /> : <I.play />}</button>
                  <button className="icon-btn" style={{ width: 30, height: 30, background: 'transparent', border: 0, color: 'var(--text-mute)' }}><I.skipfwd style={{ width: 15 }} /></button>
                  <div className="grow" />
                  {playing && <div className="eq"><i></i><i></i><i></i><i></i></div>}
                </div>
                <div className="row gap8" style={{ marginBottom: 14 }}>
                  <span className="num muted" style={{ fontSize: 11 }}>{miniElapsed}</span>
                  <div className="grow" style={{ height: 4, borderRadius: 999, background: 'var(--surface-3)', overflow: 'hidden' }}>
                    <div style={{ width: miniPct + '%', height: '100%', background: 'linear-gradient(90deg,var(--blue),var(--green))', transition: 'width .4s' }} />
                  </div>
                  <span className="num muted" style={{ fontSize: 11 }}>{miniTotal}</span>
                </div>
                <div className="divider" style={{ margin: '4px 0 12px' }} />
                {/* artist row */}
                <div className="row gap12" style={{ cursor: 'pointer' }} onClick={() => go('artist')}>
                  <div className="avatar" style={{ width: 38, height: 38, background: song.coverGrad }}></div>
                  <div className="grow">
                    <div className="row gap6" style={{ fontWeight: 700, fontSize: 14 }}>{song.artist}{song.artistId === 'nova' && <I.check style={{ width: 14, color: 'var(--blue-bright)' }} />}</div>
                    <div className="muted" style={{ fontSize: 12 }}>{song.holders.toLocaleString()} investors</div>
                  </div>
                  <button className="btn btn-ghost" style={{ padding: '6px 12px', fontSize: 12.5 }} onClick={(e) => { e.stopPropagation(); window.toast({ title: 'Following ' + song.artist, desc: 'You’ll get alerts on new offerings.' }); }}>Follow</button>
                </div>
              </div>
            </div>

            {/* metadata */}
            <div className="panel panel-pad">
              <div className="row between" style={{ marginBottom: 12 }}><h3 style={{ margin: 0, fontSize: 13, fontWeight: 700 }}>Track details</h3></div>
              {[['Released', song.year], ['Length', song.length || 'Not specified'], ['Tempo', song.bpm ? song.bpm + ' BPM' : 'Not specified'], ['Total plays', F.num(song.plays)], ['Offering', `${song.publicPct}% public`]].map(([k, v]) => (
                <div className="row between" key={k} style={{ padding: '7px 0', fontSize: 13, borderBottom: '1px solid var(--border-soft)' }}>
                  <span className="muted">{k}</span><span className="num dim">{v}</span>
                </div>
              ))}
              <div className="row gap6 wrap mt12">
                {song.tags.map((t) => <span key={t} className="tag">#{t}</span>)}
              </div>
            </div>
          </div>

          {/* ---------- CENTER ---------- */}
          <div className="col gap16" style={{ minWidth: 0 }}>
            {/* price chart */}
            <div className="panel">
              <div className="panel-head">
                <div>
                  <h3>Share price</h3>
                  <div className="sub num">{F.money(livePrice, 2)} · {liveChange >= 0 ? '+' : ''}{liveChange}% {tf}</div>
                </div>
                <div className="grow" />
                <div className="seg">
                  {TIMEFRAMES.map((t) => <button key={t} className={tf === t ? 'on' : ''} onClick={() => setTf(t)}>{t}</button>)}
                </div>
              </div>
              <div style={{ padding: '16px 14px 10px' }}>
                <C.PriceChart data={shown} up={liveChange >= 0} mode={chartMode} height={264}
                  labelFmt={(i, n) => { const m = { '1H': 'min', '24H': 'hr', '1W': 'd', '1M': 'd', 'ALL': 'd' }[tf]; return `${n - 1 - i} ${m} ago`; }} />
              </div>
            </div>

            {/* ownership + revenue */}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
              <div className="panel panel-pad">
                <h3 style={{ margin: '0 0 14px', fontSize: 13, fontWeight: 700 }}>Ownership</h3>
                <div className="row gap16" style={{ alignItems: 'center' }}>
                  <C.Donut size={132} thickness={18} segments={ownSegments} centerLabel={availOfSong.toFixed(1) + '%'} centerSub="available" />
                  <div className="col gap8" style={{ flex: 1 }}>
                    {ownSegments.map((s) => (
                      <div key={s.label} className="row gap8" style={{ fontSize: 12.5 }}>
                        <span style={{ width: 9, height: 9, borderRadius: 3, background: s.color, flex: 'none' }}></span>
                        <span className="grow muted">{s.label}</span>
                        <span className="num dim">{s.value.toFixed(1)}%</span>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
              <div className="panel panel-pad">
                <div className="row between" style={{ marginBottom: 8 }}>
                  <h3 style={{ margin: 0, fontSize: 13, fontWeight: 700 }}>Revenue</h3>
                  <span className="num pos" style={{ fontSize: 12 }}>{F.compact(song.revenue)} total</span>
                </div>
                <div className="muted" style={{ fontSize: 11, marginBottom: 10 }}>Distributed to shareholders monthly</div>
                <C.RevenueBars data={song.revBars} height={120} labels={['Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May']} />
              </div>
            </div>

            {/* trading activity */}
            <div className="panel">
              <div className="panel-head"><h3>Trading activity</h3><div className="grow" /><span className="live-dot"></span><span className="sub">live feed</span></div>
              <div style={{ padding: '4px 18px 12px' }}>
                {song.txns.slice(0, 8).map((t, i) => (
                  <div className="feed-item" key={i}>
                    <div className={'feed-dot ' + t.side}>{t.side === 'buy' ? 'B' : 'S'}</div>
                    <div className="grow">
                      <div style={{ fontSize: 13, fontWeight: 600 }}>{t.side === 'buy' ? 'Bought' : 'Sold'} <span className="num">{t.qty}</span> shares</div>
                      <div className="muted" style={{ fontSize: 11.5 }}>@{t.user} · {t.ago}m ago</div>
                    </div>
                    <div className="num" style={{ fontSize: 13, textAlign: 'right' }}>
                      <div style={{ fontWeight: 600 }}>{F.money(t.px, 2)}</div>
                      <div className={t.side === 'buy' ? 'pos' : 'neg'} style={{ fontSize: 11.5 }}>{F.money(t.qty * t.px, 0)}</div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* ---------- RIGHT ---------- */}
          <div className="col gap16 sd-right" style={{ position: 'sticky', top: 16 }}>
            <div className="panel panel-pad">
              <window.TradePanel variant={tradeVariant} price={livePrice} balance={balance} owned={owned} song={song} onTrade={onTrade} />
            </div>

            <div className="panel panel-pad">
              <h3 style={{ margin: '0 0 4px', fontSize: 13, fontWeight: 700 }}>Buy the music</h3>
              {release && (
                <div className="muted" style={{ fontSize: 12, marginBottom: 10 }}>
                  Part of the {release.type} <span className="dim" style={{ fontWeight: 600 }}>{release.title}</span>.
                </div>
              )}

              {song.owned ? (
                <div>
                  <div className="row gap6" style={{ fontSize: 12.5, fontWeight: 600, marginBottom: 10, color: 'var(--blue-bright)' }}>
                    <I.check style={{ width: 15 }} />You own this track
                  </div>
                  <a className="btn btn-primary btn-block" href={`/api/songs/${song.id}/download`} download style={{ textAlign: 'center' }}>
                    Download
                  </a>
                </div>
              ) : !song.buyable ? (
                <div className="muted" style={{ fontSize: 12, padding: '8px 0' }}>
                  This track isn’t for sale — preview only.
                </div>
              ) : (
                <>
                  <div className="muted" style={{ fontSize: 12, lineHeight: 1.5, marginBottom: 12 }}>
                    Support {song.artist} — revenue splits {song.artistPct}% to the artist / {song.publicPct}% to shareholders. Real payment, securely via Stripe.
                  </div>
                  {individualOn ? (
                    <button className="btn btn-primary btn-block" disabled={buying || !(salePrice > 0)} style={{ opacity: buying ? 0.7 : 1 }} onClick={doBuy}>
                      {buying ? 'Starting checkout…' : `Buy this track · ${F.money(salePrice, 2)}`}
                    </button>
                  ) : (
                    <div className="muted" style={{ fontSize: 12, padding: '8px 0' }}>This track is only sold as part of the {release.type}.</div>
                  )}
                </>
              )}

              {albumPrice != null && !song.owned && (
                <button className="btn btn-buy btn-block mt8" disabled={albumBuying} style={{ opacity: albumBuying ? 0.7 : 1 }} onClick={doBuyAlbum}>
                  {albumBuying ? 'Starting checkout…' : `Buy the ${release.type} · ${F.money(albumPrice, 2)}`}
                </button>
              )}
            </div>

            {owned > 0 && (
              <div className="panel panel-pad" style={{ background: 'var(--blue-tint)', borderColor: 'oklch(0.66 0.155 256 / 0.25)' }}>
                <div className="row between"><span className="muted" style={{ fontSize: 12 }}>Your position</span><I.check style={{ width: 15, color: 'var(--blue-bright)' }} /></div>
                <div className="num mt8" style={{ fontSize: 22, fontWeight: 600 }}>{owned.toLocaleString()} <span style={{ fontSize: 13, color: 'var(--text-mute)' }}>shares</span></div>
                <div className="row between mt8" style={{ fontSize: 12.5 }}><span className="muted">Market value</span><span className="num dim">{F.money(owned * livePrice, 2)}</span></div>
                <div className="row between mt4" style={{ fontSize: 12.5 }}><span className="muted">Ownership</span><span className="num dim">{((owned / song.totalShares) * 100).toFixed(3)}%</span></div>
              </div>
            )}

            <div className="panel panel-pad">
              <h3 style={{ margin: '0 0 14px', fontSize: 13, fontWeight: 700 }}>Market stats</h3>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px 12px' }}>
                {stats.map(([k, v]) => (
                  <div key={k}><div className="muted" style={{ fontSize: 11.5 }}>{k}</div><div className="num" style={{ fontSize: 15, fontWeight: 600, marginTop: 2 }}>{v}</div></div>
                ))}
              </div>
              <div className="divider mt16" style={{ marginBottom: 14 }} />
              <div className="row between"><span className="muted" style={{ fontSize: 12.5 }}>Est. annual yield</span><span className="num pos" style={{ fontSize: 16, fontWeight: 600 }}>{song.yield}%</span></div>
              <div className="muted" style={{ fontSize: 11, marginTop: 6 }}>Based on trailing 12-mo revenue distributed across {song.totalShares.toLocaleString()} shares.</div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  window.SongDetail = SongDetail;
})();
