import { describe, expect, it } from 'vitest';
import { resultBadge } from './result';
import type { GameView, Seat } from './model';

const seat = (s: number, accountId: string, score: number, isWinner = false): Seat => ({
  seat: s,
  accountId,
  displayName: accountId,
  score,
  hintsUsed: 0,
  isWinner,
});

function game(seats: Seat[], status = 'finished', toMove = 0): GameView {
  return {
    id: 'g',
    variant: 'scrabble_en',
    dictVersion: 'v1',
    vsAi: false,
    unreadChat: false,
    unreadMessages: false,
    status,
    players: seats.length,
    toMove,
    turnTimeoutSecs: 0,
    multipleWordsPerTurn: true,
    moveCount: 0,
    endReason: '',
    lastActivityUnix: 0,
    seats,
  };
}

describe('resultBadge', () => {
  it('active: your move vs opponent', () => {
    const g = game([seat(0, 'me', 5), seat(1, 'a', 3)], 'active', 0);
    expect(resultBadge(g, 'me')).toEqual({ key: 'result.yourMove', emoji: '🟢' });
    expect(resultBadge({ ...g, toMove: 1 }, 'me').key).toBe('result.oppMove');
  });

  it('open (awaiting an opponent) reads as in-progress, not a finished result', () => {
    const g = game([seat(0, 'me', 0), seat(1, '', 0)], 'open', 0);
    expect(resultBadge(g, 'me')).toEqual({ key: 'result.yourMove', emoji: '🟢' });
    expect(resultBadge({ ...g, toMove: 1 }, 'me').key).toBe('result.oppMove');
  });

  it('finished two-player: victory / defeat / draw', () => {
    expect(resultBadge(game([seat(0, 'me', 300, true), seat(1, 'a', 200)]), 'me')).toEqual({
      key: 'result.victory',
      emoji: '🏆',
    });
    expect(resultBadge(game([seat(0, 'me', 200), seat(1, 'a', 300, true)]), 'me')).toEqual({
      key: 'result.defeat',
      emoji: '🥈',
    });
    expect(resultBadge(game([seat(0, 'me', 200), seat(1, 'a', 200)]), 'me')).toEqual({
      key: 'result.draw',
      emoji: '🏅',
    });
  });

  it('finished two-player: a 0-0 resignation is a defeat, not a score-tied win', () => {
    // The opponent won by resignation (isWinner) although neither side scored — the lobby
    // must read this as a loss, matching the game-detail screen (regression).
    expect(resultBadge(game([seat(0, 'me', 0), seat(1, 'a', 0, true)]), 'me')).toEqual({
      key: 'result.defeat',
      emoji: '🥈',
    });
  });

  it('finished four-player: places by score', () => {
    const last = game([seat(0, 'me', 100), seat(1, 'a', 400, true), seat(2, 'b', 300), seat(3, 'c', 200)]);
    expect(resultBadge(last, 'me')).toEqual({ key: 'result.place4', emoji: '🏅' });
    const second = game([seat(0, 'me', 300), seat(1, 'a', 400, true), seat(2, 'b', 200), seat(3, 'c', 100)]);
    expect(resultBadge(second, 'me')).toEqual({ key: 'result.place2', emoji: '🥈' });
  });
});
