// Leaderboards and Live Events.

function LarLeaderboardsPage() {
  const names = useLarLoad(() => larApi("stats/names"), []);
  const [stat, setStat] = React.useState(null);
  const board = useLarLoad(() => (stat ? larApi(`leaderboard/${encodeURIComponent(stat)}?count=100`) : Promise.resolve(null)), [stat]);

  React.useEffect(() => {
    if (!stat && names.data?.stats?.length) setStat(names.data.stats.find(s => s.name === "BTM_Wins")?.name || names.data.stats[0].name);
  }, [names.data]);

  const entries = board.data?.entries || [];
  const top = entries[0]?.value || 1;

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Leaderboards</h1>
          <p className="page-subtitle">Top 100 per statistic. Banned players are left out. Refreshes every 30 seconds on the server.</p>
        </div>
        <div className="page-head-actions"><button className="btn btn-sm" onClick={() => board.reload()}>Refresh</button></div>
      </div>
      <div className="card card-flush">
        <div className="toolbar">
          {(names.data?.stats || []).map(s => (
            <button key={s.name} className="filter-pill" data-active={stat === s.name} onClick={() => setStat(s.name)}>{s.name} <span className="muted">· {fmt.short(s.players)}</span></button>
          ))}
          {names.data && !names.data.stats.length && <span className="tiny muted">No statistics recorded yet.</span>}
        </div>
        <table className="tbl">
          <thead><tr><th style={{width:60}}>Rank</th><th>Player</th><th>Value</th></tr></thead>
          <tbody>
            {entries.map(e => (
              <tr key={e.playerId} className="lar-row-click" onClick={() => window.larOpenPlayer(e.playerId)}>
                <td className="mono" style={{fontWeight:600}}>#{e.position + 1}</td>
                <td><div className="p-row"><PAvatar name={e.name} seed={e.playerId}/><div><div className="p-name">{e.name}</div><div className="tiny muted mono">{e.playerId}</div></div></div></td>
                <td style={{minWidth:200}}>
                  <div className="mono" style={{fontWeight:600}}>{fmt.num(e.value)}</div>
                  <div className="bar-track"><div className="bar-fill" style={{width: (e.value / top * 100) + "%", background:"var(--accent)"}}/></div>
                </td>
              </tr>
            ))}
            {stat && !board.loading && !entries.length && <tr><td colSpan={3}><div className="empty"><h3>Empty</h3><p>Nobody has a {stat} value yet.</p></div></td></tr>}
          </tbody>
        </table>
      </div>
    </div>
  );
}

const LAR_EVENT_PRESETS = [
  { id: "announcement", label: "Announcement", data: { message: "Server restart in 5 minutes" } },
  { id: "double_gold", label: "Double gold", data: { minutes: 60 } },
  { id: "lockdown", label: "Start a lockdown", data: {} },
  { id: "custom", label: "Custom", data: {} },
];

function LarEventsPage() {
  const stats = useLarLoad(() => (can("stats.view") ? larApi("stats") : Promise.resolve(null)), []);
  const history = useLarLoad(() => (can("players.view") ? larApi("audit?limit=200") : Promise.resolve(null)), []);
  const [preset, setPreset] = React.useState("announcement");
  const [name, setName] = React.useState("announcement");
  const [data, setData] = React.useState(JSON.stringify(LAR_EVENT_PRESETS[0].data, null, 2));
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [sent, setSent] = React.useState(null);

  const choose = (p) => {
    setPreset(p.id);
    if (p.id !== "custom") setName(p.id);
    setData(JSON.stringify(p.data, null, 2));
  };

  let parsed = null, problem = null;
  try { parsed = data.trim() ? JSON.parse(data) : null; } catch (e) { problem = e.message; }

  const send = async () => {
    if (!confirm(`Send "${name}" to everyone online right now?`)) return;
    setBusy(true); setError(null);
    try { setSent(await larApi("broadcast", { method: "POST", body: { name: name.trim(), data: parsed } })); history.reload(); }
    catch (e) { setError(e.message); }
    setBusy(false);
  };

  const past = (history.data?.entries || []).filter(e => e.action === "broadcast").slice(0, 20);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Live Events</h1>
          <p className="page-subtitle">Send an event to every running game this second. For something that must last (a weekend event), put it in Title Data instead: public keys are also pushed live and survive reconnects.</p>
        </div>
      </div>

      <div className="row row-2-1">
        <div className="card card-pad">
          <div className="card-head"><div><div className="card-title">Send an event</div><div className="card-sub">{stats.data ? `${fmt.num(stats.data.online)} players online right now` : "players online receive it instantly"}</div></div></div>
          <div className="h-stack gap-6 wrap mb-8">
            {LAR_EVENT_PRESETS.map(p => <button key={p.id} className="filter-pill" data-active={preset === p.id} onClick={() => choose(p)}>{p.label}</button>)}
          </div>
          <div className="field"><label>Event name</label><input className="input mono" value={name} onChange={e => setName(e.target.value)}/></div>
          <div className="field mt-8"><label>Data (JSON)</label><textarea className="input" value={data} onChange={e => setData(e.target.value)} spellCheck={false}/></div>
          {problem && <div className="tiny mt-4" style={{color:"var(--danger)"}}>{problem}</div>}
          <button className="btn btn-sm btn-accent mt-8" disabled={busy || !name.trim() || !!problem} onClick={send}><Icon name="publish" size={12}/> Send to everyone online</button>
          <LarError error={error}/>
          {sent && <div className={`lar-note ${sent.delivered ? "lar-note-ok" : ""}`}>{sent.delivered ? <><span className="lar-live-dot"/>Delivered to {fmt.num(sent.delivered)} game{sent.delivered === 1 ? "" : "s"}.</> : "Nobody is online right now."}</div>}
          <div className="lar-note" style={{marginTop:14}}>
            The game receives this as <span className="mono">LarLive.OnEvent(name, data)</span>. Nothing in the game listens yet, so an event only does something once gameplay code is hooked up to its name.
          </div>
        </div>
        <div className="card card-pad">
          <div className="card-head"><div><div className="card-title">Recently sent</div></div></div>
          <div className="stack gap-6 mt-8">
            {past.map(e => (
              <div key={e.id} style={{padding:"6px 0", borderBottom:"1px solid var(--border)"}}>
                <div className="spread"><span className="mono" style={{fontWeight:600, fontSize:12}}>{e.target}</span><span className="tiny muted">{timeSince(larIso(e.at))}</span></div>
                <div className="tiny muted">{e.actor}</div>
              </div>
            ))}
            {history.data && !past.length && <div className="empty"><h3>None yet</h3><p>Sent events show up here.</p></div>}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { LarLeaderboardsPage, LarEventsPage });
