/* ============================================================
   Arena — the exciting social layer.
   window.Arena: top live-games leaderboard (overtake + die anims)
   window.Marquee: scrolling recent results along the very bottom
   window.useBots: simulation hook driving both
   ============================================================ */
(function () {
  const { useState, useEffect, useRef, useMemo } = React;
  const E = window.Engine;

  const NAMES = ['lunatic', 'vaporSOL', 'm4xpain', 'degenDan', 'orbital', 'crashout', 'moonpig', 'jpegLord',
    'serManny', 'gwei_guy', 'apeStation', 'noFloor', 'rugfree', 'tendies', 'sol_sniper', 'pumpkin',
    'voidwalker', 'gigabrain', 'frostbyte', 'zk_zoomer', 'cosmo', 'hodlricky', 'bagchaser', 'nukem'];
  const pick = (a) => a[(Math.random() * a.length) | 0];

  function newBot(id) {
    const crash = E.genCrash();
    return {
      id, name: pick(NAMES) + ((Math.random() * 90 + 10) | 0),
      wager: +(0.01 + Math.random() * 0.09).toFixed(2),
      t0: performance.now() + Math.random() * 1500, // staggered starts
      crash, mult: 0, state: 'flying', // flying | ejected | dead
      endMult: 0, settledAt: 0,
    };
  }

  /* simulation: bots are stepped by the host game loop (no own rAF → single render path) */
  window.useBots = function useBots(n = 8) {
    const botsRef = useRef(Array.from({ length: n }, (_, i) => newBot(i)));
    const recentRef = useRef(seedRecent(28));
    const hofRef = useRef(seedHof(60));
    const stepBots = (now) => {
      const bots = botsRef.current;
      for (let i = 0; i < bots.length; i++) {
        const b = bots[i];
        if (b.state === 'flying') {
          const t = (now - b.t0) / 1000;
          if (t > 0) {
            b.mult = E.multAt(t);
            if (b.mult >= b.crash) {
              const ejected = Math.random() < 0.55 && b.crash > 0.4;
              b.state = ejected ? 'ejected' : 'dead';
              b.endMult = ejected ? +(b.crash * (0.8 + Math.random() * 0.18)).toFixed(2) : b.crash;
              b.mult = b.endMult;
              b.settledAt = now;
              pushRecent(recentRef.current, { name: b.name, mult: b.endMult, state: b.state });
              if (ejected && b.endMult >= 2.0) pushHof(hofRef.current, { name: b.name, mult: b.endMult, ts: Date.now() });
            }
          }
        } else if (now - b.settledAt > 2600) {
          bots[i] = newBot(b.id); // respawn into the rotation
        }
      }
    };
    // the player's own result joins the social layer (recent + HOF), flagged you:true
    const recordPlayer = (mult, state) => {
      pushRecent(recentRef.current, { name: 'YOU', mult, state, you: true });
      if (state === 'ejected' && mult >= 2.0) pushHof(hofRef.current, { name: 'YOU', mult, ts: Date.now(), you: true });
    };
    return { botsRef, recentRef, hofRef, stepBots, recordPlayer };
  };

  function seedRecent(k) {
    const out = [];
    for (let i = 0; i < k; i++) {
      const c = E.genCrash();
      const ej = Math.random() < 0.5 && c > 0.4;
      out.push({ id: 'r' + i + Math.random(), name: pick(NAMES) + ((Math.random() * 90 + 10) | 0), mult: ej ? +(c * 0.9).toFixed(2) : c, state: ej ? 'ejected' : 'dead' });
    }
    return out;
  }
  function pushRecent(arr, item) { arr.unshift({ id: 'r' + Math.random(), ...item }); if (arr.length > 40) arr.pop(); }

  /* hall of fame: timestamped big wins over the last 24h */
  function seedHof(k) {
    const out = [];
    const now = Date.now();
    for (let i = 0; i < k; i++) {
      // multiplier distribution skewed high; rarer = bigger
      const r = Math.random();
      const mult = +(2.0 + (-Math.log(1 - r)) * 2.4).toFixed(2);
      out.push({ id: 'h' + i + Math.random(), name: pick(NAMES) + ((Math.random() * 90 + 10) | 0), mult: Math.min(E.MAX_MULT, mult), ts: now - Math.random() * 24 * 3600 * 1000 });
    }
    return out.sort((a, b) => b.mult - a.mult);
  }
  function pushHof(arr, item) { arr.push({ id: 'h' + Math.random(), ...item }); arr.sort((a, b) => b.mult - a.mult); if (arr.length > 120) arr.length = 120; }
  function topHof(arr, windowMs, k) {
    const cut = Date.now() - windowMs;
    return arr.filter(w => w.ts >= cut).sort((a, b) => b.mult - a.mult).slice(0, k);
  }
  function agoLabel(ts) {
    const s = (Date.now() - ts) / 1000;
    if (s < 60) return Math.max(1, s | 0) + 's';
    if (s < 3600) return (s / 60 | 0) + 'm';
    return (s / 3600 | 0) + 'h';
  }

  /* ---- the live leaderboard (tabbed: LIVE / 1H / 24H) ---- */
  const ROW_H = 40, GAP = 6, SHOWN = 6;
  window.Arena = function Arena({ live, hof }) {
    const [tab, setTab] = useState('live');
    const prevRankRef = useRef({});
    const bumpRef = useRef({});
    const now = performance.now();

    // ----- LIVE tab: rank flying bots, detect overtakes -----
    const sorted = [...live].sort((a, b) => (b.mult - a.mult) || (a.id - b.id)).slice(0, SHOWN);
    if (tab === 'live') {
      sorted.forEach((b, rank) => {
        const pr = prevRankRef.current[b.id];
        if (pr != null && rank < pr && b.state === 'flying') bumpRef.current[b.id] = now + 440; // moved up = overtook
      });
      const next = {}; sorted.forEach((b, rank) => { next[b.id] = rank; });
      prevRankRef.current = next;
    }

    // HOF re-sort is expensive (≤120 items); recompute ~2×/sec instead of every frame
    const hofBucket = Math.floor(now / 500);
    const hofRows = useMemo(
      () => tab === 'live' ? null : topHof(hof, tab === '1h' ? 3600e3 : 24 * 3600e3, SHOWN),
      [tab, hofBucket, hof]
    );

    return (
      <div className="arena">
        <div className="arena-head">
          <div className="arena-tabs">
            {[['live', 'LIVE'], ['1h', '1H'], ['24h', '24H']].map(([k, lab]) => (
              <button key={k} className={'atab' + (tab === k ? ' on' : '')} onClick={() => setTab(k)}>{lab}</button>
            ))}
          </div>
          <span className="ah-count">
            {tab === 'live'
              ? <React.Fragment><span className="pp-dot" style={{ color: '#1bd760' }} />{live.filter(b => b.state === 'flying').length} flying</React.Fragment>
              : <React.Fragment><span style={{ opacity: .6 }}>top multipliers</span></React.Fragment>}
          </span>
        </div>
        <div className="arena-board" style={{ height: (ROW_H + GAP) * SHOWN }}>
          {tab === 'live' && sorted.map((b, rank) => {
            const col = E.multColor(b.mult);
            const flying = b.state === 'flying';
            const jit = flying ? Math.min(3.2, 0.4 + b.mult * 0.5) : 0;
            const big = 13 + Math.min(15, b.mult * 2.0);
            const bumping = bumpRef.current[b.id] > now;
            return (
              <div key={b.id} className={'arena-row r-' + b.state + (bumping ? ' bump' : '')}
                style={{ transform: `translateY(${rank * (ROW_H + GAP)}px)`, '--ty': (rank * (ROW_H + GAP)) + 'px', zIndex: bumping ? 5 : 1 }}>
                <span className="ar-jit" style={{ '--jit': jit + 'px', animationDuration: jit > 0 ? (0.16 - Math.min(0.06, b.mult * 0.012)) + 's' : '0s' }}>
                  <span className="ar-rank">{rank + 1}</span>
                  <span className="ar-name">{b.name}</span>
                  {b.state === 'ejected' && <span className="ar-badge ej">EJECT</span>}
                  {b.state === 'dead' && <span className="ar-badge dead">REKT</span>}
                  <span className="ar-spark" style={{ '--c': col }}><Spark mult={b.mult} flying={flying} /></span>
                  <span className="ar-mult" style={{ color: col, fontSize: big, textShadow: flying ? `0 0 14px ${col}66` : 'none' }}>{E.fmtMult(b.mult)}x</span>
                </span>
              </div>
            );
          })}
          {tab !== 'live' && hofRows.map((w, rank) => {
            const col = E.multColor(w.mult);
            const big = 14 + Math.min(15, w.mult * 1.6);
            return (
              <div key={w.id} className={'arena-row r-hof' + (w.you ? ' r-you' : '')} style={{ transform: `translateY(${rank * (ROW_H + GAP)}px)` }}>
                <span className="ar-rank">{rank === 0 ? '👑' : rank + 1}</span>
                <span className="ar-name">{w.you ? 'YOU' : w.name}</span>
                <span className="ar-ago">{agoLabel(w.ts)} ago</span>
                <span className="ar-mult" style={{ color: col, fontSize: big }}>{E.fmtMult(w.mult)}x</span>
              </div>
            );
          })}
          {tab !== 'live' && hofRows.length === 0 && <div className="arena-empty">no big wins yet this window</div>}
        </div>
      </div>
    );
  };

  function Spark({ mult, flying }) {
    // tiny rising sparkline; height encodes mult
    const pts = [];
    const n = 14;
    for (let i = 0; i < n; i++) {
      const f = i / (n - 1);
      const y = 18 - Math.min(17, (mult * f) * 5 + Math.sin(i + mult) * 1.2);
      pts.push(`${f * 46},${y}`);
    }
    return (
      <svg width="46" height="20" viewBox="0 0 46 20" style={{ opacity: flying ? 0.9 : 0.3 }}>
        <polyline points={pts.join(' ')} fill="none" stroke="var(--c)" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    );
  }

  /* ---- bottom marquee of recent results ---- */
  window.Marquee = function Marquee({ recent }) {
    const items = recent.slice(0, 26);
    return (
      <div className="marquee">
        <div className="marquee-track">
          {[0, 1].map(half => items.map((r) => (
            <span key={r.id + '-' + half} className={'mq-item ' + r.state + (r.you ? ' mq-you' : '')}>
              <span className="mq-name">{r.you ? 'YOU' : r.name}</span>
              <span className="mq-mult" style={{ color: E.multColor(r.mult) }}>{E.fmtMult(r.mult)}x</span>
              <span className={'mq-dot ' + r.state} />
            </span>
          )))}
        </div>
      </div>
    );
  };
})();
