/**
 * SimplifiedSelector — unit tests
 * Tests the data contracts and logic that the SimplifiedSelector component relies on.
 * Since the frontend uses Next.js/React without jest-dom configured in the Node test suite,
 * we test the underlying data shapes, stat lists, and line pre-fill logic.
 */

describe('SimplifiedSelector', () => {
  const NBA_STATS = ['points', 'rebounds', 'assists', 'threes', 'blocks', 'steals', 'pra', 'turnovers'];
  const MLB_STATS = [
    'strikeouts', 'hits_allowed', 'earned_runs', 'innings_pitched', 'walks_allowed',
    'hits', 'total_bases', 'rbi', 'runs', 'stolen_bases', 'home_runs', 'walks', 'singles', 'doubles',
  ];

  // Test 1: Sport toggle renders correctly (data contract)
  test('sport toggle has exactly NBA and MLB options', () => {
    const sports = ['NBA', 'MLB'];
    expect(sports).toHaveLength(2);
    expect(sports).toContain('NBA');
    expect(sports).toContain('MLB');
  });

  test('NBA stat list contains expected prop types', () => {
    expect(NBA_STATS).toContain('points');
    expect(NBA_STATS).toContain('rebounds');
    expect(NBA_STATS).toContain('assists');
    expect(NBA_STATS).toContain('threes');
    expect(NBA_STATS).toContain('pra');
    expect(NBA_STATS).toHaveLength(8);
  });

  test('MLB stat list contains expected prop types', () => {
    expect(MLB_STATS).toContain('strikeouts');
    expect(MLB_STATS).toContain('hits');
    expect(MLB_STATS).toContain('total_bases');
    expect(MLB_STATS).toContain('home_runs');
    expect(MLB_STATS).toHaveLength(14);
  });

  // Test 2: Player search accepts text input (logic contract)
  test('player search requires minimum 2 characters before querying', () => {
    const shouldSearch = (query) => query.length >= 2;
    expect(shouldSearch('')).toBe(false);
    expect(shouldSearch('L')).toBe(false);
    expect(shouldSearch('Le')).toBe(true);
    expect(shouldSearch('LeBron')).toBe(true);
  });

  // Test 3: Stat dropdown populates from player selection
  test('stat dropdown filters to available odds when player has odds data', () => {
    const playerOdds = [
      { player: 'LeBron James', stat_type: 'points', line: 25.5, direction: 'over', book: 'draftkings' },
      { player: 'LeBron James', stat_type: 'rebounds', line: 7.5, direction: 'over', book: 'draftkings' },
      { player: 'LeBron James', stat_type: 'assists', line: 7.5, direction: 'over', book: 'fanduel' },
    ];

    const availableStats = NBA_STATS.filter((s) => playerOdds.some((o) => o.stat_type === s));
    expect(availableStats).toEqual(['points', 'rebounds', 'assists']);
    expect(availableStats).not.toContain('threes');
  });

  test('stat dropdown shows all stats when no odds data available', () => {
    const playerOdds = [];
    const availableStats = playerOdds.length > 0
      ? NBA_STATS.filter((s) => playerOdds.some((o) => o.stat_type === s))
      : NBA_STATS;
    expect(availableStats).toEqual(NBA_STATS);
  });

  // Test 4: Line pre-fills when player and stat selected
  test('line pre-fills from matching odds data', () => {
    const playerOdds = [
      { player: 'LeBron James', stat_type: 'points', line: 25.5, direction: 'over', book: 'draftkings' },
      { player: 'LeBron James', stat_type: 'rebounds', line: 7.5, direction: 'under', book: 'fanduel' },
    ];

    const selectedStat = 'points';
    const match = playerOdds.find((o) => o.stat_type === selectedStat);
    expect(match).toBeDefined();
    expect(match.line).toBe(25.5);
    expect(match.direction).toBe('over');
  });

  test('line stays empty when no matching odds for selected stat', () => {
    const playerOdds = [
      { player: 'LeBron James', stat_type: 'points', line: 25.5, direction: 'over', book: 'draftkings' },
    ];

    const selectedStat = 'blocks';
    const match = playerOdds.find((o) => o.stat_type === selectedStat);
    expect(match).toBeUndefined();
  });

  // Test 5: Grade card renders after scan completes (data shape contract)
  test('scan result contains grade data needed for GradeCard rendering', () => {
    const mockResult = {
      scan_id: 'test-123',
      parlay_grade: 'B',
      parlay_confidence: 72,
      correlation_flags: [],
      legs: [{
        index: 0,
        player: 'LeBron James',
        stat_type: 'points',
        line: 25.5,
        direction: 'over',
        grade: 'A',
        confidence: 85,
        edge_pct: 4.2,
        kill_conditions: [],
        reasoning_summary: 'Strong recent form supports the over.',
      }],
      scan_count: 1,
      scans_remaining: 4,
      upgrade_pitch: null,
    };

    expect(mockResult.parlay_grade).toBeDefined();
    expect(mockResult.parlay_confidence).toBeDefined();
    expect(mockResult.legs[0].grade).toBeDefined();
    expect(mockResult.legs[0].confidence).toBeDefined();
    expect(['A', 'B', 'C', 'D']).toContain(mockResult.legs[0].grade);
  });

  // Sport switching resets state
  test('switching sport should reset stat list', () => {
    let currentSport = 'NBA';
    let stats = currentSport === 'NBA' ? NBA_STATS : MLB_STATS;
    expect(stats).toContain('points');

    currentSport = 'MLB';
    stats = currentSport === 'NBA' ? NBA_STATS : MLB_STATS;
    expect(stats).toContain('strikeouts');
    expect(stats).not.toContain('points');
  });

  // Scan payload shape
  test('scan payload includes all required fields', () => {
    const payload = {
      player: 'LeBron James',
      stat_type: 'points',
      line: 25.5,
      direction: 'over',
      sport: 'NBA',
    };

    expect(payload).toHaveProperty('player');
    expect(payload).toHaveProperty('stat_type');
    expect(payload).toHaveProperty('line');
    expect(payload).toHaveProperty('direction');
    expect(payload).toHaveProperty('sport');
    expect(typeof payload.line).toBe('number');
  });
});
