'use strict';

// Job 1 — per-sport snapshot cadence config. Locks the posting-rhythm map and
// the two quota-discipline invariants so a future edit can't silently
// reintroduce baseball's one-size-fits-all rhythm.

const cadence = require('../../src/config/sportCadence');
const { HOURS_UTC } = require('../../src/snapshotScheduler');

describe('sportCadence', () => {
  test('every sport is a subset of the scheduler firing grid (else it never runs)', () => {
    // The scheduler only fires at HOURS_UTC; a sport hour outside that set would
    // be silently dropped. This invariant is the whole reason the design keeps
    // the union inside the grid.
    for (const orphan of cadence.ALL_HOURS.filter((h) => !HOURS_UTC.includes(h))) {
      throw new Error(`hour ${orphan} is scheduled for some sport but not in HOURS_UTC=${HOURS_UTC}`);
    }
    expect(cadence.ALL_HOURS.every((h) => HOURS_UTC.includes(h))).toBe(true);
  });

  test('WNBA keeps the full grid — PropLine-cheap; catches afternoon + late west-coast games', () => {
    // Corrected from reality (2026-07-15: afternoon WNBA games finished before
    // the 22 UTC slot). 14 UTC (10am ET) is the only slot early enough for a
    // 1pm ET game's props; on PropLine the extra slots cost a rounding error.
    expect(cadence.hoursFor('wnba')).toEqual([14, 19, 22, 1, 3]);
    expect(cadence.sportsForHour(14)).toContain('wnba');
  });

  test('soccer is the ONLY restricted sport — two lean odds-api slots, never the full grid', () => {
    // The genuine cadence win is protecting the 500/mo odds-api key. PropLine
    // sports run the full grid cheaply; soccer alone is trimmed.
    expect(cadence.hoursFor('soccer')).toEqual([14, 19]);
    expect(cadence.sportsForHour(22)).not.toContain('soccer');
    expect(cadence.sportsForHour(1)).not.toContain('soccer');
    expect(cadence.sportsForHour(3)).not.toContain('soccer');
  });

  test('soccer is excluded from intraday (protects the 500/mo odds-api key)', () => {
    expect(cadence.intradaySports()).not.toContain('soccer');
    expect(cadence.intradaySports()).toEqual(expect.arrayContaining(['mlb', 'nba', 'wnba']));
  });

  test('sportsForHour respects a candidate subset and unknown hours yield none', () => {
    expect(cadence.sportsForHour(19, ['wnba', 'soccer'])).toEqual(expect.arrayContaining(['wnba', 'soccer']));
    expect(cadence.sportsForHour(7)).toEqual([]); // 7 UTC — nobody posts
  });

  test('mlb keeps the full baseball grid', () => {
    expect(cadence.hoursFor('mlb')).toEqual([14, 19, 22, 1, 3]);
  });
});
