// MLB context helpers (Session 15) — pitcher handedness + lineup PA.

const { platoonAdvantage, projectedPA, __internals } = require('../../src/services/intelligence/mlbContext');

describe('platoonAdvantage', () => {
  test('LHP vs RHB → batter has advantage', () => {
    expect(platoonAdvantage('L', 'R')).toBe(true);
  });
  test('RHP vs LHB → batter has advantage', () => {
    expect(platoonAdvantage('R', 'L')).toBe(true);
  });
  test('LHP vs LHB → pitcher has advantage', () => {
    expect(platoonAdvantage('L', 'L')).toBe(false);
  });
  test('RHP vs RHB → pitcher has advantage', () => {
    expect(platoonAdvantage('R', 'R')).toBe(false);
  });
  test('switch hitter ALWAYS has the edge (vs LHP)', () => {
    expect(platoonAdvantage('L', 'S')).toBe(true);
  });
  test('switch hitter ALWAYS has the edge (vs RHP)', () => {
    expect(platoonAdvantage('R', 'S')).toBe(true);
  });
  test('null pitcher → null', () => {
    expect(platoonAdvantage(null, 'R')).toBeNull();
  });
  test('null batter → null', () => {
    expect(platoonAdvantage('L', null)).toBeNull();
  });
  test('invalid input → null (does not throw)', () => {
    expect(platoonAdvantage('Z', 'R')).toBeNull();
    expect(platoonAdvantage('L', 'X')).toBeNull();
  });
  test('case-insensitive', () => {
    expect(platoonAdvantage('l', 'r')).toBe(true);
    expect(platoonAdvantage('Right', 'Left')).toBe(true);
  });
  test('whitespace tolerant', () => {
    expect(platoonAdvantage(' L ', ' R ')).toBe(true);
  });
});

describe('projectedPA', () => {
  test('leadoff (1) sees the most PAs (~4.7)', () => {
    expect(projectedPA(1)).toBeGreaterThan(4.6);
    expect(projectedPA(1)).toBeLessThan(4.8);
  });
  test('9-hole sees the fewest PAs (~3.7)', () => {
    expect(projectedPA(9)).toBeGreaterThan(3.6);
    expect(projectedPA(9)).toBeLessThan(3.8);
  });
  test('PA decreases monotonically by slot', () => {
    let prev = Infinity;
    for (let i = 1; i <= 9; i += 1) {
      const pa = projectedPA(i);
      expect(pa).toBeLessThan(prev);
      prev = pa;
    }
  });
  test('numeric string input is accepted', () => {
    expect(projectedPA('3')).toBeCloseTo(4.43, 2);
  });
  test('out-of-range returns null', () => {
    expect(projectedPA(0)).toBeNull();
    expect(projectedPA(10)).toBeNull();
    expect(projectedPA(-1)).toBeNull();
  });
  test('null / undefined / non-numeric → null', () => {
    expect(projectedPA(null)).toBeNull();
    expect(projectedPA(undefined)).toBeNull();
    expect(projectedPA('NaN')).toBeNull();
  });
  test('non-integer (e.g. 5.5) → null', () => {
    expect(projectedPA(5.5)).toBeNull();
  });
});

describe('normalizeHand', () => {
  test('accepts L, R, S in upper/lower case', () => {
    expect(__internals.normalizeHand('l')).toBe('L');
    expect(__internals.normalizeHand('R')).toBe('R');
    expect(__internals.normalizeHand('Switch')).toBe('S');
  });
  test('rejects unknown letters', () => {
    expect(__internals.normalizeHand('X')).toBeNull();
    expect(__internals.normalizeHand('')).toBeNull();
    expect(__internals.normalizeHand(null)).toBeNull();
  });
});
