// Session 64 (A1-S5) — prop viability: lineup confirmation + injury wire +
// the NOT-IN grade kill. Real feeds only; absent → no chips, never guessed.

const { parseLineups, statusFor } = require('../../src/services/lineupService');
const { parseInjuries, chipFor } = require('../../src/services/injuryService');
const adapter = require('../../web/src/lib/slateAdapter');

// Real statsapi hydrate=lineups shape (verified live 2026-07-11).
const SCHEDULE_JSON = {
  dates: [{
    games: [
      {
        gamePk: 823357,
        teams: { home: { team: { name: 'Milwaukee Brewers' } }, away: { team: { name: 'Pittsburgh Pirates' } } },
        lineups: {
          homePlayers: [
            { id: 663968, fullName: 'Jake Mangum' },
            { id: 664040, fullName: 'Brandon Lowe' },
          ],
          awayPlayers: [{ id: 1, fullName: 'Bryan Reynolds' }],
        },
      },
      { gamePk: 823356, teams: { home: { team: { name: 'Detroit Tigers' } }, away: { team: { name: 'Tampa Bay Rays' } } }, lineups: {} },
    ],
  }],
};

describe('lineupService — CONFIRMED / NOT_IN / PROJECTED', () => {
  const parsed = parseLineups(SCHEDULE_JSON);

  test('posted lineup → confirmed with the batting slot', () => {
    expect(parsed.byPlayer['brandon lowe']).toEqual({ status: 'confirmed', slot: 2, team: 'Milwaukee Brewers' });
    expect(parsed.postedTeams).toContain('Milwaukee Brewers');
  });

  test('team posted, player absent → NOT_IN', () => {
    expect(statusFor('Christian Yelich', 'Milwaukee Brewers', parsed).status).toBe('not_in');
  });

  test('team not posted → PROJECTED (never guessed dead)', () => {
    expect(statusFor('Riley Greene', 'Detroit Tigers', parsed).status).toBe('projected');
  });

  test('accented/variant names resolve through nameKey', () => {
    expect(statusFor('Brandon Lowé', 'Milwaukee Brewers', parsed).status).toBe('confirmed');
  });
});

describe('injuryService — OUT / GTD / PROB chips', () => {
  test('parses the ESPN feed shape', () => {
    const byPlayer = parseInjuries({
      injuries: [{
        displayName: 'Arizona Diamondbacks',
        injuries: [
          { athlete: { displayName: 'Ketel Marte' }, status: 'Out', details: { type: 'Hamstring' } },
          { athlete: { displayName: 'Corbin Carroll' }, status: 'Day-To-Day', shortComment: 'wrist' },
        ],
      }],
    });
    expect(byPlayer['ketel marte']).toMatchObject({ status: 'OUT', detail: 'Hamstring' });
    expect(byPlayer['corbin carroll'].status).toBe('GTD');
  });
  test('unknown status text → no chip (never invented)', () => {
    expect(chipFor('Active')).toBeNull();
    expect(chipFor('')).toBeNull();
  });
});

describe('slateAdapter — NOT_IN kills the graded props on the strip', () => {
  const GAME = { home: 'Milwaukee Brewers', away: 'Pittsburgh Pirates' };
  const props = [{ player: 'Christian Yelich', stat_type: 'hits', line: 0.5 }];
  const gradeIndex = adapter.indexGrades([
    { player: 'Christian Yelich', stat_type: 'hits', line: 0.5, direction: 'over', grade: 'A',
      team: 'Milwaukee Brewers', gradedAt: { line: 0.5, timestamp: 'x' } },
  ]);
  // Fixture keys computed via nameKey — the same folding BOTH real sides use
  // (hand-written keys miss nickname resolution, e.g. jake→jacob).
  const { nameKey } = require('../../web/src/lib/playerName');
  const viability = {
    lineups: { byPlayer: { [nameKey('Jake Mangum')]: { status: 'confirmed', slot: 1 } }, postedTeams: ['Milwaukee Brewers'] },
    injuries: {},
  };

  test('graded prop for a NOT_IN player renders dead (grade preserved)', () => {
    const strips = adapter.buildPlayerStripsFromProps(props, gradeIndex, {}, Date.now(), GAME, viability);
    expect(strips[0].lineup.status).toBe('not_in');
    expect(strips[0].props[0].dead).toBe(true);
    expect(strips[0].props[0].grade).toBe('A'); // struck through in UI, never deleted
  });

  test('confirmed player carries the slot; no viability feed → no chips', () => {
    const confirmed = adapter.buildPlayerStripsFromProps(
      [{ player: 'Jake Mangum', stat_type: 'hits', line: 0.5 }],
      {}, {}, Date.now(), GAME, viability,
    );
    expect(confirmed[0].lineup).toEqual({ status: 'confirmed', slot: 1 });
    const none = adapter.buildPlayerStripsFromProps(props, gradeIndex, {}, Date.now(), GAME, null);
    expect(none[0].lineup == null).toBe(true);
    expect(none[0].props[0].dead == null).toBe(true);
  });
});
