/* SignalShade scoreboard: every house bot's live record against 200 random-entry runs over the same
 * hours (/api/strategies/house-scoreboard, built by src/house_bots.js scoreboard()). Shown at the top of
 * each SignalShade strategy page. */

const HB_REFRESH_MS = 10 * 60 * 1000;
const hbR = (x) => (x == null ? '–' : `${x > 0 ? '+' : ''}${Number(x).toFixed(2)}R`);
const hbTone = (x) => (x == null || x === 0 ? 'var(--text-2)' : x > 0 ? 'var(--bull)' : 'var(--bear)');
const hbDay = (ms) => new Date(ms).toLocaleDateString([], { day: 'numeric', month: 'short' });
const HB_CHIP = { beats: 'bull', trails: 'bear', luck: 'neutral', early: 'neutral' };

function W_HouseScoreboard({ currentId }) {
  const [state, setState] = React.useState({ data: null, error: null, loading: true });
  React.useEffect(() => {
    let cancelled = false, timer;
    const load = () => {
      fetch('/api/strategies/house-scoreboard')
        .then((r) => r.json())
        .then((j) => { if (!cancelled) setState({ data: j.ok ? j.data : null, error: j.ok ? null : (j.error || 'unavailable'), loading: false }); })
        .catch(() => { if (!cancelled) setState((s) => ({ ...s, error: 'unavailable', loading: false })); })
        .finally(() => { if (!cancelled) timer = setTimeout(load, HB_REFRESH_MS); });
    };
    load();
    return () => { cancelled = true; clearTimeout(timer); };
  }, []);
  return <HB_View data={state.data} loading={state.loading} error={state.error} currentId={currentId} />;
}

/** Where each bot's total sits against the random runs' range (p5 to p95 shaded, median marked). */
function HB_Band({ luck, bots, currentId }) {
  const vals = bots.map((b) => b.live.totalR).concat([luck.p5, luck.p95]);
  const lo = Math.min(...vals), hi = Math.max(...vals);
  const pad = Math.max(0.5, (hi - lo) * 0.08), a = lo - pad, b = hi + pad;
  const x = (v) => `${((v - a) / (b - a)) * 100}%`;
  return (
    <div style={{ margin: '4px 0 16px' }}>
      <div style={{ position: 'relative', height: 46 }}>
        <div style={{ position: 'absolute', top: 20, left: 0, right: 0, height: 1, background: 'var(--border)' }} />
        <div title={`Middle 90% of ${luck.seeds} random runs`} style={{ position: 'absolute', top: 12, height: 17, left: x(luck.p5), width: `calc(${x(luck.p95)} - ${x(luck.p5)})`, background: 'var(--bg-elev, rgba(127,127,127,0.12))', border: '1px dashed var(--text-4)', borderRadius: 4 }} />
        <div title="Median random run" style={{ position: 'absolute', top: 9, height: 23, width: 2, left: x(luck.median), background: 'var(--text-4)' }} />
        {bots.map((bt) => (
          <div key={bt.strategyId} title={`${bt.name}: ${hbR(bt.live.totalR)}`} style={{
            position: 'absolute', top: 15, left: x(bt.live.totalR), width: 11, height: 11, marginLeft: -5.5, borderRadius: '50%',
            background: bt.control ? 'var(--text-3)' : hbTone(bt.live.totalR || 0.0001),
            border: bt.strategyId === currentId ? '2px solid var(--text)' : '2px solid var(--bg-card)',
          }} />
        ))}
        <div style={{ position: 'absolute', top: 34, left: x(luck.p5), transform: 'translateX(-50%)', fontSize: 10, color: 'var(--text-4)' }}>{hbR(luck.p5)}</div>
        <div style={{ position: 'absolute', top: 34, left: x(luck.p95), transform: 'translateX(-50%)', fontSize: 10, color: 'var(--text-4)' }}>{hbR(luck.p95)}</div>
      </div>
      <div style={{ fontSize: 11, color: 'var(--text-3)', marginTop: 2 }}>
        Dashed box: where 90% of {luck.seeds} random-entry runs ended over the same hours (line = the middle one). Dots: each bot.
      </div>
    </div>
  );
}

function HB_View({ data: d, loading, error, currentId }) {
  const th = { textAlign: 'left', fontWeight: 500, fontSize: 10.5, color: 'var(--text-4)', textTransform: 'uppercase', letterSpacing: '0.06em', padding: '6px 10px 6px 0', whiteSpace: 'nowrap' };
  const td = { padding: '8px 10px 8px 0', fontSize: 12.5, borderTop: '1px solid var(--border)', whiteSpace: 'nowrap', verticalAlign: 'top' };
  return (
    <div className="card" style={{ marginBottom: 14 }}>
      <div className="card-h" style={{ flexWrap: 'wrap', gap: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
          <h3 style={{ margin: 0 }}>SignalShade scoreboard</h3>
          <span className="chip neutral" title="Paper trades only: no account follows these bots">paper only</span>
        </div>
        {d && <span style={{ fontSize: 10.5, color: 'var(--text-4)' }}>live since {hbDay(d.since)} · updated {new Date(d.asOf).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>}
      </div>
      <div className="card-b">
        {!d ? (
          <div style={{ padding: '24px 0', textAlign: 'center', color: 'var(--text-3)', fontSize: 12.5 }}>
            {loading ? 'Loading… (replaying 200 random runs)' : 'The scoreboard is unavailable right now. It will retry shortly.'}
          </div>
        ) : (
          <>
            <p style={{ margin: '0 0 12px', fontSize: 12.5, color: 'var(--text-2)', lineHeight: 1.5 }}>
              Is a bot good or just lucky? Each one is compared with {d.luck ? d.luck.seeds : 200} runs of random entries
              (the Coin flip rules) over the same hours. A bot only counts as better than luck once it beats 95% of them,
              and it needs at least {d.minTrades} closed trades first. R = multiples of the risk taken per trade, after fees and funding.
            </p>
            {d.luck && d.luck.p95 - d.luck.p5 >= 0.01
              ? <HB_Band luck={d.luck} bots={d.bots} currentId={currentId} />
              : <div style={{ fontSize: 12, color: 'var(--text-3)', margin: '0 0 12px' }}>
                  The random range is still empty: too few hours have passed for random entries to win or lose much. It fills in over the next days.
                </div>}
            <div style={{ overflowX: 'auto' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead>
                  <tr>
                    <th style={th}>Bot</th><th style={th}>Now</th><th style={th}>Closed</th><th style={th}>Win</th>
                    <th style={th}>Total</th><th style={th}>Vs random</th><th style={th} title={`Backtest ${d.backtestPeriod}`}>Backtest 3y</th>
                  </tr>
                </thead>
                <tbody>
                  {d.bots.map((b) => {
                    const o = b.live.open;
                    return (
                      <tr key={b.strategyId} style={b.strategyId === currentId ? { background: 'var(--bg-card-2, rgba(127,127,127,0.07))' } : null}>
                        <td style={{ ...td, fontWeight: b.strategyId === currentId ? 600 : 400 }}>
                          {b.name}{b.control && <span style={{ color: 'var(--text-4)', fontSize: 11 }}> · control</span>}
                        </td>
                        <td style={td}>
                          {o ? <span><span className={`chip ${o.side === 'long' ? 'bull' : 'bear'}`}>{o.side}</span>{' '}
                            <span style={{ color: hbTone(o.r), fontSize: 11.5 }}>{hbR(o.r)}</span>
                            <span style={{ color: 'var(--text-4)', fontSize: 11 }}> since {hbDay(o.since)}</span></span>
                            : <span style={{ color: 'var(--text-4)' }}>flat</span>}
                        </td>
                        <td style={td}>{b.live.trades}</td>
                        <td style={td}>{b.live.winRate == null ? '–' : `${b.live.winRate}%`}</td>
                        <td style={{ ...td, color: hbTone(b.live.totalR), fontWeight: 500 }}>{b.live.trades ? hbR(b.live.totalR) : '–'}</td>
                        <td style={td}><span className={`chip ${HB_CHIP[b.verdict.key] || 'neutral'}`}>{b.verdict.text}</span></td>
                        <td style={{ ...td, color: hbTone(b.backtest && b.backtest.totalR) }}
                          title={b.backtest ? `${b.backtest.trades} trades · last year ${hbR(b.backtest.lastYearR)} · worst drawdown ${b.backtest.maxDdR}R` : ''}>
                          {b.backtest ? hbR(b.backtest.totalR) : '–'}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
            <div style={{ fontSize: 11, color: 'var(--text-4)', marginTop: 10, lineHeight: 1.5 }}>
              Backtest: {d.backtestPeriod}, same rules and costs. The Coin flip's backtest is one lucky draw: over 200 draws the
              middle result was −15.9R, which is what fees do to random trading.
            </div>
          </>
        )}
      </div>
    </div>
  );
}
