import { describe, expect, it } from 'vitest';
import { goalEvents, halfTimeScore, parseEvents } from './matchEvents';
import type { MatchLiveEvent } from './types';

// Real shapes from the ESPN feed (WC 2026 match 2, Korea Republic – Czechia).
const realEvents: MatchLiveEvent[] = [
  { minute: null, type: 'Kickoff', text: '', team: null },
  { minute: 23, type: 'Start Delay', text: 'Delay in match for a drinks break.', team: 'home' },
  { minute: 23, type: 'Start Delay', text: '', team: 'away' },
  { minute: 25, type: 'End Delay', text: 'Delay over. They are ready to continue.', team: 'home' },
  { minute: 25, type: 'End Delay', text: '', team: 'away' },
  { minute: 45, type: 'Halftime', text: '', team: null },
  { minute: 45, type: 'Start 2nd Half', text: '', team: null },
  {
    minute: 59, type: 'Goal - Header', team: 'away',
    text: 'Goal! Korea Republic 0, Czechia 1. Ladislav Krejcí (Czechia) header from very close range to the bottom right corner. Assisted by Vladimír Coufal with a cross.',
  },
  { minute: 62, type: 'Substitution', text: 'Substitution, Korea Republic. Hwang Hee-Chan replaces Lee Jae-Sung.', team: 'home' },
  {
    minute: 67, type: 'Goal', team: 'home',
    text: 'Goal! Korea Republic 1, Czechia 1. Hwang In-Beom (Korea Republic) right footed shot from the centre of the box to the bottom right corner. Assisted by Lee Kang-In.',
  },
  { minute: 90, type: 'Yellow Card', text: 'Lee Gi-Hyuk (Korea Republic) is shown the yellow card for a bad foul.', team: 'home' },
  { minute: 90, type: 'End Regular Time', text: '', team: null },
];

describe('parseEvents', () => {
  it('drops whole-match markers and empty duplicate rows', () => {
    const parsed = parseEvents(realEvents);
    expect(parsed.map((e) => e.kind)).toEqual(['other', 'other', 'goal', 'sub', 'goal', 'yellow']);
  });

  it('parses scorer, assist and the running score from goal text', () => {
    const goals = goalEvents(realEvents);
    expect(goals[0]).toMatchObject({
      side: 'away', minute: 59, title: 'Ladislav Krejcí', score: [0, 1],
      detail: { type: 'assist', name: 'Vladimír Coufal' },
    });
    expect(goals[1]).toMatchObject({
      side: 'home', minute: 67, title: 'Hwang In-Beom', score: [1, 1],
      detail: { type: 'assist', name: 'Lee Kang-In' },
    });
  });

  it('parses substitutions into in/out players', () => {
    const sub = parseEvents(realEvents).find((e) => e.kind === 'sub');
    expect(sub).toMatchObject({ title: 'Hwang Hee-Chan', subOut: 'Lee Jae-Sung', side: 'home' });
  });

  it('parses the booked player from card text', () => {
    const card = parseEvents(realEvents).find((e) => e.kind === 'yellow');
    expect(card).toMatchObject({ title: 'Lee Gi-Hyuk', side: 'home' });
  });

  it('renders neutral happenings centered (side null) with their text', () => {
    const delay = parseEvents(realEvents)[0];
    expect(delay).toMatchObject({ kind: 'other', side: null, title: 'Delay in match for a drinks break.' });
  });

  it('handles own goals', () => {
    const [g] = parseEvents([{
      minute: 30, type: 'Own Goal', team: 'home',
      text: 'Own Goal by Joe Gomez, England. Scotland 1, England 0.',
    }]);
    expect(g).toMatchObject({ kind: 'goal', title: 'Joe Gomez', detail: { type: 'ownGoal' }, score: [1, 0] });
  });

  it('marks converted penalties', () => {
    const [g] = parseEvents([{
      minute: 75, type: 'Penalty - Scored', team: 'away',
      text: 'Goal! Mexico 0, Brazil 2. Vinícius Júnior (Brazil) converts the penalty with a right footed shot to the bottom left corner.',
    }]);
    expect(g).toMatchObject({ kind: 'goal', title: 'Vinícius Júnior', detail: { type: 'penalty' }, score: [0, 2] });
  });

  it('falls back to counting by side when the text has no score', () => {
    const parsed = parseEvents([
      { minute: 10, type: 'Goal', text: 'Scrappy finish.', team: 'home' },
      { minute: 20, type: 'Goal', text: 'Another one.', team: 'home' },
    ]);
    expect(parsed[0]?.score).toEqual([1, 0]);
    expect(parsed[1]?.score).toEqual([2, 0]);
  });

  it('never produces an empty title', () => {
    for (const e of parseEvents(realEvents)) expect(e.title.length).toBeGreaterThan(0);
  });
});

describe('halfTimeScore', () => {
  it('is the last goal score at minute ≤ 45', () => {
    expect(halfTimeScore(parseEvents(realEvents))).toEqual([0, 0]);
    const withEarly = parseEvents([
      { minute: 12, type: 'Goal', text: 'Goal! A 1, B 0. Someone (A) shot.', team: 'home' },
      { minute: 70, type: 'Goal', text: 'Goal! A 1, B 1. Other (B) shot.', team: 'away' },
    ]);
    expect(halfTimeScore(withEarly)).toEqual([1, 0]);
  });
});
