import { describe, it, expect } from 'vitest';
import { rankGroup, type Result } from './standings';

const r = (home: string, away: string, hs: number, as: number): Result => ({
  home, away, homeScore: hs, awayScore: as,
});

describe('rankGroup', () => {
  it('orders by points first', () => {
    const rows = rankGroup(['A', 'B', 'C', 'D'], [
      r('A', 'B', 1, 0), // A 3pts
      r('C', 'D', 2, 2), // C,D 1pt
    ]);
    expect(rows[0]!.team).toBe('A');
    expect(rows[0]!.points).toBe(3);
    expect(rows[0]!.rank).toBe(1);
  });

  it('breaks equal points by goal difference, then goals for', () => {
    const rows = rankGroup(['A', 'B'], [
      r('A', 'B', 3, 0), // A +3
      r('B', 'A', 1, 0), // B beats A; now both 3pts, A gd 0 gf3, B gd 0 gf1
    ]);
    // both 3 pts, gd 0; A has more goals for (3 vs 1) → A first
    expect(rows[0]!.team).toBe('A');
  });

  it('uses head-to-head when points, GD and GF are all level', () => {
    // A and B identical overall (each beat C by same score, drew nobody else),
    // separated only by their head-to-head meeting.
    const rows = rankGroup(['A', 'B', 'C'], [
      r('A', 'C', 2, 0),
      r('B', 'C', 2, 0),
      r('A', 'B', 1, 0), // A wins the head-to-head
    ]);
    // After all games: A 6pts? no — A: beat C, beat B = 6; B: beat C, lost A = 3.
    // Make them level instead:
    const level = rankGroup(['A', 'B', 'C', 'D'], [
      r('A', 'C', 1, 0),
      r('B', 'C', 1, 0),
      r('A', 'D', 0, 1),
      r('B', 'D', 0, 1),
      r('A', 'B', 2, 1), // identical records (1W 1L, GF? ) but A beat B head-to-head
    ]);
    void rows;
    const ia = level.findIndex((x) => x.team === 'A');
    const ib = level.findIndex((x) => x.team === 'B');
    expect(ia).toBeLessThan(ib);
  });

  it('assigns sequential ranks and includes all teams even with no games', () => {
    const rows = rankGroup(['A', 'B', 'C', 'D'], []);
    expect(rows).toHaveLength(4);
    expect(rows.map((x) => x.rank)).toEqual([1, 2, 3, 4]);
    expect(rows.every((x) => x.played === 0)).toBe(true);
  });
});
