const { computeStats, getWeekStart } = require('../../src/services/performanceService');

describe('performanceService', () => {
  describe('computeStats', () => {
    test('calculates ROI correctly from won/lost mix', () => {
      const bets = [
        { amount: '20', potential_payout: '38.18', status: 'won', settled_at: '2026-03-21' },
        { amount: '20', potential_payout: '38.18', status: 'lost', settled_at: '2026-03-21' },
        { amount: '20', potential_payout: '38.18', status: 'won', settled_at: '2026-03-21' },
      ];
      const stats = computeStats(bets);
      // Won: 18.18 + 18.18 = 36.36 profit, Lost: -20 = -20
      // Total profit: 16.36, Total wagered: 60
      // ROI: 16.36/60 * 100 = 27.3%
      expect(stats.roi).toBeCloseTo(27.3, 0);
      expect(stats.total_wagered).toBe(60);
      expect(stats.total_profit).toBeCloseTo(16.36, 1);
    });

    test('win rate = won / (won + lost), excludes push', () => {
      const bets = [
        { amount: '20', potential_payout: '38', status: 'won', settled_at: '2026-03-21' },
        { amount: '20', potential_payout: '38', status: 'lost', settled_at: '2026-03-21' },
        { amount: '20', potential_payout: '38', status: 'push', settled_at: '2026-03-21' },
      ];
      const stats = computeStats(bets);
      expect(stats.win_rate).toBe(50);
      expect(stats.sample_size).toBe(3);
    });

    test('empty bets returns zeroes', () => {
      const stats = computeStats([]);
      expect(stats.roi).toBe(0);
      expect(stats.win_rate).toBe(0);
      expect(stats.sample_size).toBe(0);
      expect(stats.total_wagered).toBe(0);
      expect(stats.total_profit).toBe(0);
    });

    test('all losses gives negative ROI', () => {
      const bets = [
        { amount: '20', potential_payout: '38', status: 'lost', settled_at: '2026-03-21' },
        { amount: '30', potential_payout: '57', status: 'lost', settled_at: '2026-03-21' },
      ];
      const stats = computeStats(bets);
      expect(stats.roi).toBe(-100);
      expect(stats.win_rate).toBe(0);
    });
  });

  describe('getWeekStart', () => {
    test('returns Monday for a Wednesday', () => {
      // 2026-03-18 is a Wednesday
      const ws = getWeekStart(new Date('2026-03-18T12:00:00Z'));
      expect(ws.getUTCDay()).toBe(1); // Monday
      expect(ws.toISOString().split('T')[0]).toBe('2026-03-16');
    });

    test('returns Monday for a Monday', () => {
      const ws = getWeekStart(new Date('2026-03-16T12:00:00Z'));
      expect(ws.toISOString().split('T')[0]).toBe('2026-03-16');
    });

    test('returns previous Monday for a Sunday', () => {
      // 2026-03-22 is a Sunday
      const ws = getWeekStart(new Date('2026-03-22T12:00:00Z'));
      expect(ws.toISOString().split('T')[0]).toBe('2026-03-16');
    });
  });
});
