// Unit: book comparison service (Session 28). Pure functions.

const { compareProp, bestLines } = require('../../src/services/bookComparisonService');

const prop = {
  player: 'Wembanyama',
  stat_type: 'points',
  lines: [
    { book: 'draftkings', line: 28.5, over_odds: -110, under_odds: -110 },
    { book: 'fanduel', line: 28.5, over_odds: -105, under_odds: -115 }, // best over
    { book: 'betmgm', line: 28.5, over_odds: -120, under_odds: -102 },  // best under
  ],
};

describe('bookComparisonService — compareProp', () => {
  test('identifies the best OVER line (highest payout)', () => {
    const c = compareProp(prop, 'over');
    expect(c.bestBook).toBe('fanduel'); // -105 pays more than -110/-120
    expect(c.bestOdds).toBe(-105);
    expect(c.books.find((b) => b.book === 'fanduel').isBest).toBe(true);
    expect(c.bookCount).toBe(3);
  });

  test('identifies the best UNDER line', () => {
    const c = compareProp(prop, 'under');
    expect(c.bestBook).toBe('betmgm'); // -102 pays more than -110/-115
    expect(c.bestOdds).toBe(-102);
  });

  test('savings is positive (best beats the field average)', () => {
    const c = compareProp(prop, 'over');
    expect(c.savings).toBeGreaterThan(0);
  });

  test('single-book prop still compares (bookCount 1)', () => {
    const c = compareProp({ player: 'X', stat_type: 'hits', lines: [{ book: 'dk', over_odds: -110 }] }, 'over');
    expect(c.bookCount).toBe(1);
    expect(c.bestBook).toBe('dk');
  });

  test('no usable lines → null, not crash', () => {
    expect(compareProp({ player: 'X', stat_type: 'hits', lines: [] }, 'over')).toBeNull();
    expect(compareProp({ player: 'X', stat_type: 'hits' }, 'over')).toBeNull();
  });
});

describe('bookComparisonService — bestLines', () => {
  test('drops single-book props and sorts by savings desc', () => {
    const props = [
      prop,
      { player: 'Solo', stat_type: 'reb', lines: [{ book: 'dk', over_odds: -110 }] }, // 1 book → dropped
      {
        player: 'BigEdge', stat_type: 'ast',
        lines: [
          { book: 'dk', over_odds: -200 },
          { book: 'fd', over_odds: +120 }, // huge spread → big savings
        ],
      },
    ];
    const lines = bestLines(props, { side: 'over' });
    expect(lines.map((l) => l.player)).not.toContain('Solo');
    expect(lines[0].player).toBe('BigEdge'); // biggest savings first
  });

  test('non-array input → empty', () => {
    expect(bestLines(null)).toEqual([]);
  });
});
