import { describe, expect, it } from 'vitest';
import { groupScenarios } from './scenarios';
import type { Fixture } from './types';

const slot = (team: string) => ({ team, placeholder: null, label: team });
const fx = (num: number, home: string, away: string, hs: number | null, as: number | null): Fixture => ({
  num, stage: 'group', group: 'A', round: 'Matchday', groupRound: null,
  kickoff: `2026-06-${10 + num}T18:00:00Z`, venue: 'X',
  home: slot(home), away: slot(away),
  status: hs == null ? 'scheduled' : 'finished', homeScore: hs, awayScore: as, minute: null,
} as Fixture);

const TEAMS = ['A', 'B', 'C', 'D'];

describe('groupScenarios', () => {
  it('returns null before the closing stretch (4+ open matches)', () => {
    const fxs = [fx(1, 'A', 'B', 1, 0), fx(2, 'C', 'D', null, null), fx(3, 'A', 'C', null, null), fx(4, 'B', 'D', null, null), fx(5, 'A', 'D', null, null), fx(6, 'B', 'C', null, null)];
    expect(groupScenarios(TEAMS, fxs)).toBeNull();
  });

  it('returns null when the group is finished', () => {
    const fxs = [fx(1, 'A', 'B', 1, 0), fx(2, 'C', 'D', 0, 0), fx(3, 'A', 'C', 2, 0), fx(4, 'B', 'D', 1, 1), fx(5, 'A', 'D', 1, 0), fx(6, 'B', 'C', 0, 0)];
    expect(groupScenarios(TEAMS, fxs)).toBeNull();
  });

  it('a team that won everything is guaranteed top-2 before the last round', () => {
    // A beat B and C; final matchday: A-D and B-C remain → 9 combos
    const fxs = [
      fx(1, 'A', 'B', 2, 0), fx(2, 'C', 'D', 1, 0),
      fx(3, 'A', 'C', 1, 0), fx(4, 'B', 'D', 0, 0),
      fx(5, 'A', 'D', null, null), fx(6, 'B', 'C', null, null),
    ];
    const sc = groupScenarios(TEAMS, fxs)!;
    const a = sc.find((s) => s.team === 'A')!;
    expect(a.totalCombos).toBe(9);
    expect(a.guaranteed).toBe(true); // 6 pts; only one team can reach 6 besides A → A is at worst 2nd
    const d = sc.find((s) => s.team === 'D')!;
    expect(d.alive).toBe(true); // D can win and others break right
    expect(d.guaranteed).toBe(false);
  });

  it('safeWithWin reflects winning the remaining match', () => {
    const fxs = [
      fx(1, 'A', 'B', 2, 0), fx(2, 'C', 'D', 1, 0),
      fx(3, 'A', 'C', 1, 0), fx(4, 'B', 'D', 0, 0),
      fx(5, 'A', 'D', null, null), fx(6, 'B', 'C', null, null),
    ];
    const sc = groupScenarios(TEAMS, fxs)!;
    // C on 3 pts: beats B in the last round → 6 pts; A guaranteed 1st-or-2nd…
    const c = sc.find((s) => s.team === 'C')!;
    expect(c.safeWithWin).not.toBeNull();
    expect(c.alive).toBe(true);
  });

  it('totals are consistent', () => {
    const fxs = [
      fx(1, 'A', 'B', 2, 0), fx(2, 'C', 'D', 1, 0),
      fx(3, 'A', 'C', 1, 0), fx(4, 'B', 'D', 0, 0),
      fx(5, 'A', 'D', null, null), fx(6, 'B', 'C', null, null),
    ];
    const sc = groupScenarios(TEAMS, fxs)!;
    for (const s of sc) {
      expect(s.top2Count).toBeGreaterThanOrEqual(0);
      expect(s.top2Count).toBeLessThanOrEqual(s.totalCombos);
      expect(s.alive).toBe(s.top2Count > 0);
      expect(s.guaranteed).toBe(s.top2Count === s.totalCombos);
    }
    // exactly 2 qualify per combo → sum of counts = 2 × combos
    expect(sc.reduce((sum, s) => sum + s.top2Count, 0)).toBe(2 * 9);
  });
});
