// Fun Stats screen — opens from Final, breaks down sniper / lost-in-time / wildest miss /
// bullseyes / decade champs / accuracy chart / safest / boldest. Ported from the design at
// design/hitster/project/e2e-screens.jsx (FunStats + computeFunStats + FunStatsChart).

(() => {
const R = window.R;
const { Tag, Btn, RisoStamp, Screen, risoTex } = window;

function decadeOf(year) {
  if (!Number.isFinite(year)) return '?';
  const d = Math.floor(year / 10) * 10;
  return `${String(d).slice(2)}s`;
}

// history = [{ song: { title, year }, guesses: [{ id, name, color, guess, dist, points }] }]
function computeFunStats(history) {
  if (!history?.length) return null;
  const byPlayer = {};
  history.forEach(({ song, guesses }) => {
    guesses.forEach((g) => {
      if (!byPlayer[g.name]) byPlayer[g.name] = {
        name: g.name, color: g.color,
        dists: [], guesses: [], rounds: [], decadeDists: {},
      };
      // Skip if this player didn't guess this round (no value)
      if (g.guess == null || !Number.isFinite(g.dist)) return;
      byPlayer[g.name].dists.push(g.dist);
      byPlayer[g.name].guesses.push(g.guess);
      byPlayer[g.name].rounds.push({ song, guess: g.guess, dist: g.dist });
      const dec = decadeOf(song.year);
      if (!byPlayer[g.name].decadeDists[dec]) byPlayer[g.name].decadeDists[dec] = [];
      byPlayer[g.name].decadeDists[dec].push(g.dist);
    });
  });

  const players = Object.values(byPlayer).filter(p => p.dists.length > 0);
  if (players.length === 0) return null;
  const avg = (arr) => arr.length ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;

  const withAvg = players.map((p) => ({ ...p, avg: avg(p.dists) }));
  const sniper = withAvg.slice().sort((a, b) => a.avg - b.avg)[0];
  const lost   = withAvg.slice().sort((a, b) => b.avg - a.avg)[0];

  // Wildest miss
  let wildest = { dist: -1 };
  history.forEach(({ song, guesses }) => {
    guesses.forEach((g) => {
      if (Number.isFinite(g.dist) && g.dist > wildest.dist) {
        wildest = { name: g.name, dist: g.dist, song: song.title, actual: song.year, guess: g.guess };
      }
    });
  });

  const bullseyes = [];
  history.forEach(({ song, guesses }) => {
    guesses.forEach((g) => {
      if (g.dist === 0) bullseyes.push({ name: g.name, year: song.year, song: song.title });
    });
  });

  const decades = {};
  history.forEach(({ song }) => {
    const d = decadeOf(song.year);
    decades[d] = (decades[d] || 0) + 1;
  });
  const decadeChamps = Object.keys(decades).sort().map((d) => {
    const ranked = players.map((p) => ({
      name: p.name,
      dist: p.decadeDists[d] ? avg(p.decadeDists[d]) : Infinity,
    })).sort((a, b) => a.dist - b.dist);
    if (!ranked[0] || ranked[0].dist === Infinity) return null;
    return { decade: d, name: ranked[0].name, dist: Math.round(ranked[0].dist), songs: decades[d] };
  }).filter(Boolean);

  const safest = players.map((p) => {
    const counts = {};
    p.guesses.forEach((y) => { counts[y] = (counts[y] || 0) + 1; });
    const top = Object.entries(counts).sort((a, b) => b[1] - a[1])[0];
    return { name: p.name, year: top ? top[0] : '—', repeats: top ? top[1] : 0 };
  }).sort((a, b) => b.repeats - a.repeats)[0];

  const boldest = players.map((p) => ({
    name: p.name,
    spread: p.guesses.length ? Math.max(...p.guesses) - Math.min(...p.guesses) : 0,
  })).sort((a, b) => b.spread - a.spread)[0];

  return { sniper, lost, wildest, bullseyes, decadeChamps, safest, boldest };
}

function FunStatsChart({ history }) {
  const W = 280, H = 90, PAD = 6;
  const series = {};
  history.forEach(({ guesses }, ri) => {
    guesses.forEach((g) => {
      if (g.guess == null || !Number.isFinite(g.dist)) return;
      if (!series[g.name]) series[g.name] = { name: g.name, color: g.color, points: [] };
      series[g.name].points.push({ r: ri, dist: g.dist });
    });
  });
  const lines = Object.values(series);
  const allDists = lines.flatMap((l) => l.points.map((p) => p.dist));
  const maxDist = Math.max(8, ...allDists);
  const xAt = (r) => PAD + (r * (W - PAD * 2)) / Math.max(1, history.length - 1 || 1);
  const yAt = (d) => PAD + (d / maxDist) * (H - PAD * 2);

  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', background: R.paper, border: `2px solid ${R.ink}` }}>
        <line x1={PAD} y1={PAD} x2={W - PAD} y2={PAD} stroke={R.green} strokeWidth="1" strokeDasharray="3 3" />
        {lines.map((l) => (
          <g key={l.name}>
            <polyline
              fill="none" stroke={l.color} strokeWidth="2.2"
              strokeLinecap="round" strokeLinejoin="round"
              points={l.points.map((p) => `${xAt(p.r)},${yAt(p.dist)}`).join(' ')}
            />
            {l.points.map((p, i) => (
              <circle key={i} cx={xAt(p.r)} cy={yAt(p.dist)} r="3" fill={l.color} stroke={R.ink} strokeWidth="1.5" />
            ))}
          </g>
        ))}
      </svg>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 6 }}>
        {lines.map((l) => (
          <div key={l.name} style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
            <div style={{ width: 10, height: 10, background: l.color, border: `1.5px solid ${R.ink}` }} />
            <span style={{ fontSize: 10, fontWeight: 800 }}>{l.name}</span>
          </div>
        ))}
        <div style={{ marginLeft: 'auto', fontSize: 9, fontWeight: 700, color: R.muted, letterSpacing: '.1em' }}>
          ↑ FARTHER · ↓ CLOSER
        </div>
      </div>
    </div>
  );
}

function FunStats({ history, onBack, onNewGame }) {
  const stats = React.useMemo(() => computeFunStats(history), [history]);

  if (!stats || !history || history.length === 0) {
    return (
      <Screen>
        <div style={{ padding: '8px 22px', display: 'flex', justifyContent: 'space-between' }}>
          <Tag color={R.ink}>Fun stats</Tag>
          <span style={{ fontSize: 11, fontWeight: 800, letterSpacing: '.14em', cursor: 'pointer' }} onClick={onBack}>← BACK</span>
        </div>
        <div style={{ flex: 1, padding: '40px 22px', fontSize: 13, color: R.muted, fontWeight: 700, textAlign: 'center' }}>
          No round history yet — play a few rounds and come back.
        </div>
      </Screen>
    );
  }

  const cardBase = {
    padding: '12px 14px', border: `2px solid ${R.ink}`, background: R.paper2,
    boxShadow: `3px 3px 0 ${R.ink}`,
  };

  return (
    <Screen>
      <RisoStamp size={280} color={R.yellow} top={-100} left={-80} duration={28} />

      <div style={{ padding: '8px 22px', display: 'flex', justifyContent: 'space-between', position: 'relative', zIndex: 5 }}>
        <Tag color={R.ink}>The breakdown</Tag>
        <span style={{ fontSize: 11, fontWeight: 800, letterSpacing: '.14em', cursor: 'pointer' }} onClick={onBack}>← BACK</span>
      </div>

      <div style={{ padding: '14px 22px 8px', flex: 1, display: 'flex', flexDirection: 'column', gap: 10, overflowY: 'auto', position: 'relative', zIndex: 4 }}>

        <div style={{ ...cardBase, background: R.green, color: R.ink, backgroundImage: risoTex('rgba(26,26,26,.08)', 3) }}>
          <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.24em' }}>🎯 SNIPER</div>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginTop: 4 }}>
            <div style={{ fontSize: 26, fontWeight: 900, letterSpacing: '-.02em' }}>{stats.sniper.name.toUpperCase()}</div>
            <div style={{ fontSize: 16, fontWeight: 900, fontFamily: 'ui-monospace, monospace' }}>{stats.sniper.avg.toFixed(1)} yr avg</div>
          </div>
          <div style={{ fontSize: 11, fontWeight: 700, marginTop: 2, opacity: .8 }}>Closest overall — guessed nearest to the truth across all rounds.</div>
        </div>

        <div style={{ ...cardBase, background: R.pink, color: R.paper, backgroundImage: risoTex('rgba(245,239,226,.08)', 3) }}>
          <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.24em' }}>🌫 LOST IN TIME</div>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginTop: 4 }}>
            <div style={{ fontSize: 26, fontWeight: 900, letterSpacing: '-.02em' }}>{stats.lost.name.toUpperCase()}</div>
            <div style={{ fontSize: 16, fontWeight: 900, fontFamily: 'ui-monospace, monospace' }}>{stats.lost.avg.toFixed(1)} yr avg</div>
          </div>
          <div style={{ fontSize: 11, fontWeight: 700, marginTop: 2, opacity: .9 }}>Farthest from the truth on average. Need a history book.</div>
        </div>

        <div style={{ ...cardBase, display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ width: 8, height: 36, background: R.yellow, border: `2px solid ${R.ink}` }} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.22em', color: R.muted }}>💥 WILDEST MISS</div>
            <div style={{ fontSize: 15, fontWeight: 900, marginTop: 1, lineHeight: 1.15 }}>
              {stats.wildest.name} · <span style={{ color: R.pink }}>{stats.wildest.dist}</span> yrs off
            </div>
            <div style={{ fontSize: 11, fontWeight: 600, color: R.muted, marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              "{stats.wildest.song}" · {stats.wildest.actual} → guessed {stats.wildest.guess}
            </div>
          </div>
        </div>

        {stats.bullseyes.length > 0 && (
          <div style={{ ...cardBase, background: R.yellow }}>
            <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.22em' }}>🎯 BULLSEYES · EXACT YEAR</div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 6 }}>
              {stats.bullseyes.map((b, i) => (
                <div key={i} style={{
                  padding: '4px 8px', background: R.ink, color: R.paper,
                  fontSize: 11, fontWeight: 900, letterSpacing: '.04em',
                }}>{b.name} · {b.year}</div>
              ))}
            </div>
          </div>
        )}

        {stats.decadeChamps.length > 0 && (
          <div style={cardBase}>
            <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.22em', color: R.muted }}>🏆 DECADE CHAMPS</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6, marginTop: 6 }}>
              {stats.decadeChamps.map((d, i) => (
                <div key={i} style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  padding: '6px 8px', border: `2px solid ${R.ink}`, background: R.paper,
                }}>
                  <div style={{
                    width: 36, fontSize: 14, fontWeight: 900, letterSpacing: '-.02em', color: R.blue,
                  }}>{d.decade}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12, fontWeight: 900, lineHeight: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{d.name}</div>
                    <div style={{ fontSize: 9, fontWeight: 700, color: R.muted, marginTop: 1 }}>{d.dist}yr off · {d.songs}sg</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        <div style={cardBase}>
          <div style={{ fontSize: 10, fontWeight: 900, letterSpacing: '.22em', color: R.muted, marginBottom: 8 }}>📈 ACCURACY BY ROUND</div>
          <FunStatsChart history={history} />
        </div>

        <div style={{ display: 'flex', gap: 8 }}>
          <div style={{ flex: 1, ...cardBase, background: R.blue, color: R.paper, backgroundImage: risoTex('rgba(245,239,226,.08)', 3) }}>
            <div style={{ fontSize: 9, fontWeight: 900, letterSpacing: '.2em' }}>🧊 SAFEST</div>
            <div style={{ fontSize: 16, fontWeight: 900, marginTop: 2 }}>{stats.safest.name}</div>
            <div style={{ fontSize: 10, fontWeight: 700, opacity: .85 }}>guessed {stats.safest.year} most</div>
          </div>
          <div style={{ flex: 1, ...cardBase, background: R.ink, color: R.paper, backgroundImage: risoTex('rgba(245,239,226,.06)', 3) }}>
            <div style={{ fontSize: 9, fontWeight: 900, letterSpacing: '.2em', color: R.yellow }}>🔥 BOLDEST</div>
            <div style={{ fontSize: 16, fontWeight: 900, marginTop: 2 }}>{stats.boldest.name}</div>
            <div style={{ fontSize: 10, fontWeight: 700, opacity: .75 }}>widest year spread</div>
          </div>
        </div>
      </div>

      <div style={{ padding: '8px 22px 0', display: 'flex', gap: 8 }}>
        <div style={{ flex: 1 }}>
          <Btn bg={R.paper2} big={false} onClick={onBack}>← BACK</Btn>
        </div>
        {onNewGame && (
          <div style={{ flex: 1 }}>
            <Btn bg={R.green} big={false} onClick={onNewGame}>NEW GAME</Btn>
          </div>
        )}
      </div>
    </Screen>
  );
}

window.FunStats = FunStats;
window.computeFunStats = computeFunStats;
})();
