import { Fragment, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useGameStore } from '../store/gameStore';
import { emit, socket } from '../lib/socket';
import { useIsDesktop } from '../lib/useIsDesktop';
import { displayName } from '../lib/names';
import type { GameDetail, GameDetailRound } from '../types';

function fmtDate(iso: string | null): string {
  if (!iso) return '—';
  const d = new Date(iso);
  return isNaN(d.getTime()) ? '—' : d.toLocaleString('sk-SK');
}

export default function History() {
  const navigate = useNavigate();
  const history = useGameStore((s) => s.history);
  const detail = useGameStore((s) => s.gameDetail);
  const setGameDetail = useGameStore((s) => s.setGameDetail);

  useEffect(() => {
    emit.getPlayerHistory();
    return () => setGameDetail(null);
  }, [setGameDetail]);

  // After a prematurely-ended game is reopened, the server confirms with
  // `game_restored`; jump to the lobby where it now shows as resumable.
  useEffect(() => {
    const onRestored = () => navigate('/');
    socket.on('game_restored', onRestored);
    return () => {
      socket.off('game_restored', onRestored);
    };
  }, [navigate]);

  // --- detail view ---
  if (detail) {
    return <GameDetailView detail={detail} onBack={() => setGameDetail(null)} />;
  }

  // --- list view ---
  return (
    <div className="max-w-md mx-auto p-4 pt-8 min-h-screen">
      <div className="flex items-center justify-between mb-6">
        <h1 className="font-serif text-2xl text-gold">Moja história</h1>
        <button onClick={() => navigate('/')} className="text-sm text-green-dim hover:text-gold">
          Späť
        </button>
      </div>

      {history.length === 0 && (
        <p className="text-center text-green-dim py-6">Zatiaľ žiadne odohrané hry.</p>
      )}

      <div className="flex flex-col gap-3">
        {history.map((g) => (
          <div
            key={g.gid}
            className="flex items-stretch bg-header border border-[#142018] rounded-xl overflow-hidden"
          >
            <button
              onClick={() => emit.getGameDetail(g.gid)}
              className="flex-1 min-w-0 text-left px-4 py-3 hover:bg-white/[.02] transition-colors"
            >
              <p className="font-serif text-green-score truncate">{g.name || 'Hra'}</p>
              <p className="text-xs text-green-dim mt-1 truncate">{g.players.map((n) => displayName(n)).join(', ')}</p>
              <p className="text-xs text-[#7a7058] mt-0.5">
                {fmtDate(g.created_at)} · {g.completed ? 'dohraná' : 'predčasne ukončená'}
              </p>
            </button>
            <div className="flex flex-col items-end justify-center gap-2 py-3 pl-2 pr-3">
              <span className="text-base font-serif text-gold whitespace-nowrap leading-none">
                {g.my_points}
                <span className="text-[11px] text-green-dim ml-0.5">b.</span>
              </span>
              {!g.completed && (
                <button
                  onClick={() => emit.restoreGame(g.gid)}
                  className="px-4 py-1.5 rounded-lg text-sm font-serif font-semibold bg-gold text-table hover:bg-gold-bright transition-colors whitespace-nowrap"
                >
                  Obnoviť
                </button>
              )}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

const SEP = '1px solid rgba(201,168,76,.16)'; // vertical divider between players
const DESKTOP_COLS = '28px repeat(8,1fr)'; // index + 4 players × 2 series columns
const MOBILE_COLS = '28px repeat(4,1fr)'; // index + 4 players (one series stacked)

/** Scoreboard-style detail. Desktop: 4 player columns in the header (total
 *  beside the name), and under each a pair of series side by side — series 1 &
 *  2 on top, 3 & 4 below, separated by a blank row. Mobile: the same 4 player
 *  columns, but the series stack one below another. Per round a cell shows the
 *  points (hit bid) or the struck-through bid (missed → 0); each series ends
 *  with a Σ total. */
function GameDetailView({ detail, onBack }: { detail: GameDetail; onBack: () => void }) {
  const desktop = useIsDesktop();
  const seats = detail.players; // seat order 0..3
  const seatIds = seats.map((p) => p.player_id);
  const totals = seatIds.map((pid) =>
    detail.rounds.reduce((a, r) => (r.player_id === pid ? a + r.points : a), 0),
  );

  // series -> round -> playerId -> round entry
  const bySeries = useMemo(() => {
    const m = new Map<number, Map<number, Map<number, GameDetailRound>>>();
    for (const r of detail.rounds) {
      let rounds = m.get(r.series_number);
      if (!rounds) m.set(r.series_number, (rounds = new Map()));
      let byPlayer = rounds.get(r.round_number);
      if (!byPlayer) rounds.set(r.round_number, (byPlayer = new Map()));
      byPlayer.set(r.player_id, r);
    }
    return m;
  }, [detail.rounds]);
  const seriesNums = [...bySeries.keys()].sort((a, b) => a - b);
  const roundsOf = (s: number | undefined) =>
    s === undefined ? [] : [...(bySeries.get(s)?.keys() ?? [])];

  const cellNode = (s: number | undefined, rn: number, seat: number) => {
    const r = s === undefined ? undefined : bySeries.get(s)?.get(rn)?.get(seatIds[seat]);
    if (!r) return null;
    return r.won ? (
      <span className="font-serif" style={{ fontSize: 14, color: '#c8bb95' }}>{r.points}</span>
    ) : (
      <span className="font-serif" style={{ fontSize: 14, color: '#7a6e4a' }}>{r.guess}</span>
    );
  };
  const seriesTotal = (s: number | undefined, seat: number) =>
    s === undefined
      ? ''
      : [...(bySeries.get(s)?.values() ?? [])].reduce(
          (a, byP) => a + (byP.get(seatIds[seat])?.points ?? 0),
          0,
        );

  // Header: player names with their grand total beside the name (both layouts).
  const header = (
    <div
      className="border-b border-gold/[.18]"
      style={{ display: 'grid', gridTemplateColumns: MOBILE_COLS, padding: '9px 8px' }}
    >
      <div />
      {seats.map((p, c) => (
        <div
          key={c}
          style={{
            display: 'flex',
            alignItems: 'baseline',
            justifyContent: 'center',
            gap: 6,
            borderLeft: c > 0 ? SEP : undefined,
          }}
        >
          <span className="uppercase text-gold" style={{ letterSpacing: '.06em', fontSize: 11 }}>
            {displayName(p.username)}
          </span>
          <span className="font-serif text-gold-dim" style={{ fontWeight: 700, fontSize: 16 }}>
            {totals[c]}
          </span>
        </div>
      ))}
    </div>
  );

  // A round row: index column + one cell per (player × series) in `cols`.
  const roundRow = (rn: number, cols: (number | undefined)[]) => (
    <div
      key={rn}
      className="border-b border-gold/[.04]"
      style={{
        display: 'grid',
        gridTemplateColumns: desktop ? DESKTOP_COLS : MOBILE_COLS,
        alignItems: 'center',
        padding: '3px 8px',
      }}
    >
      <div style={{ textAlign: 'center', fontSize: 10, color: '#7a7252' }}>{rn + 1}</div>
      {seats.map((_, c) =>
        cols.map((s, si) => (
          <div key={`${c}-${si}`} style={{ textAlign: 'center', borderLeft: c > 0 && si === 0 ? SEP : undefined }}>
            {cellNode(s, rn, c)}
          </div>
        )),
      )}
    </div>
  );

  // Σ row: per-series totals for each player.
  const sigmaRow = (cols: (number | undefined)[]) => (
    <div
      className="bg-gold/[.08] border-b border-gold/[.14]"
      style={{
        display: 'grid',
        gridTemplateColumns: desktop ? DESKTOP_COLS : MOBILE_COLS,
        alignItems: 'center',
        padding: '5px 8px',
      }}
    >
      <div className="text-green-dim" style={{ textAlign: 'center', fontSize: 11 }}>Σ</div>
      {seats.map((_, c) =>
        cols.map((s, si) => (
          <div
            key={`${c}-${si}`}
            className="font-serif text-green-score"
            style={{ textAlign: 'center', fontWeight: 600, fontSize: 14, borderLeft: c > 0 && si === 0 ? SEP : undefined }}
          >
            {seriesTotal(s, c)}
          </div>
        )),
      )}
    </div>
  );

  // Tiny row telling which series each sub-column is (desktop only — always a
  // fixed pair, sB may be absent for a trailing odd series).
  const seriesTags = (sA: number, sB: number | undefined) => (
    <div
      className="border-b border-gold/10"
      style={{ display: 'grid', gridTemplateColumns: DESKTOP_COLS, padding: '5px 8px 3px' }}
    >
      <div />
      {seats.map((_, c) => (
        <Fragment key={c}>
          <div style={{ textAlign: 'center', fontSize: 10, color: '#8a8064', borderLeft: c > 0 ? SEP : undefined }}>
            {sA + 1}
          </div>
          <div style={{ textAlign: 'center', fontSize: 10, color: '#8a8064' }}>
            {sB !== undefined ? sB + 1 : ''}
          </div>
        </Fragment>
      ))}
    </div>
  );

  // Desktop: pair series side by side (S1|S2, then S3|S4) with a blank row between.
  const desktopBody = (() => {
    const blocks: number[][] = [];
    for (let i = 0; i < seriesNums.length; i += 2) blocks.push(seriesNums.slice(i, i + 2));
    return blocks.map((block, bi) => {
      const [sA, sB] = block;
      const roundNums = [...new Set([...roundsOf(sA), ...roundsOf(sB)])].sort((a, b) => a - b);
      return (
        <Fragment key={bi}>
          {seriesTags(sA, sB)}
          {roundNums.map((rn) => roundRow(rn, [sA, sB]))}
          {sigmaRow([sA, sB])}
          {bi < blocks.length - 1 && <div style={{ height: 12 }} />}
        </Fragment>
      );
    });
  })();

  // Mobile: one series per block, stacked vertically, 4 player columns each.
  const mobileBody = seriesNums.map((s, si) => {
    const roundNums = roundsOf(s).sort((a, b) => a - b);
    return (
      <Fragment key={s}>
        <div style={{ padding: '7px 8px 3px', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.09em', color: '#8a8064' }}>
          Séria {s + 1}
        </div>
        {roundNums.map((rn) => roundRow(rn, [s]))}
        {sigmaRow([s])}
        {si < seriesNums.length - 1 && <div style={{ height: 12 }} />}
      </Fragment>
    );
  });

  return (
    <div className="max-w-lg mx-auto p-4 pt-8 min-h-screen">
      <button onClick={onBack} className="text-sm text-green-dim hover:text-gold mb-4">
        ← Späť na zoznam
      </button>
      <h1 className="font-serif text-2xl text-gold mb-1 truncate">{detail.name || 'Detail hry'}</h1>
      <p className="text-xs text-green-dim mb-4">{fmtDate(detail.created_at)}</p>

      {/* Desktop packs 8 columns → allow horizontal scroll on narrow widths;
          mobile uses only 4 columns and fits the phone, so no scroll. */}
      <div className={`bg-header border border-[#142018] rounded-xl ${desktop ? 'overflow-x-auto' : ''}`}>
        <div style={desktop ? { minWidth: 440 } : undefined}>
          {header}
          {desktop ? desktopBody : mobileBody}
        </div>
      </div>
    </div>
  );
}
