import { beforeEach, describe, expect, it, vi } from 'vitest';

vi.mock('../corner-scout', () => ({
  isSoccerLeague: (league: string) => ['epl', 'la_liga', 'serie_a', 'bundesliga', 'ligue_1'].includes(league),
}));

vi.mock('../kenpom', () => ({
  computeKenPomMOVScore: vi.fn(() => ({ confidence: 0.72, gamesPlayed: 28, predictedMOV: 7.5 })),
}));

import { calculateComposite } from '../composite-score';

describe('composite-score', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('uses NBA weights when digimon picks are available', () => {
    const result = calculateComposite({
      grokConfidence: 0.7,
      grokValueRating: 8,
      piffProps: [{ edge: 0.4, name: 'LeBron James', stat: 'PTS', line: 27.5, direction: 'over', tier_label: 'T1_LOCK' }] as any,
      digimonPicks: [{ player: 'Player A', prop: 'REB', line: 8.5, missRate: 0.2, verdict: 'LOCK' }] as any,
      dvp: { home: null, away: null },
      league: 'nba',
    });

    expect(result.edgeBreakdown.weights).toEqual({ grok: 0.35, piff: 0.35, digimon: 0.30 });
    expect(result.stormCategory).toBe(4);
  });

  it('redistributes NBA weights when digimon is unavailable', () => {
    const result = calculateComposite({
      grokConfidence: 0.62,
      grokValueRating: 6,
      piffProps: [{ edge: 0.2, name: 'LeBron James', stat: 'PTS', line: 27.5, direction: 'over', tier_label: 'T2' }] as any,
      digimonPicks: [],
      dvp: { home: null, away: null },
      league: 'nba',
    });

    expect(result.edgeBreakdown.weights).toEqual({ grok: 0.60, piff: 0.40, digimon: 0 });
  });

  it('uses kenpom weights for ncaab matchups', () => {
    const result = calculateComposite({
      grokConfidence: 0.68,
      grokValueRating: 7,
      piffProps: [],
      digimonPicks: [],
      dvp: { home: null, away: null },
      league: 'ncaab',
      kenpomMatchup: { home: { adjEM: 20 }, away: { adjEM: 15 } },
    });

    expect(result.edgeBreakdown.weights).toEqual({ grok: 0.55, kenpom: 0.45 });
    expect(result.modelSignals.piff).toBeNull();
    expect(result.edgeBreakdown.kenpomScore).toBeDefined();
  });

  it('uses corner scout in soccer blends', () => {
    const result = calculateComposite({
      grokConfidence: 0.6,
      grokValueRating: 5,
      piffProps: [{ edge: 0.18, name: 'Player', stat: 'Corners', line: 2.5, direction: 'over', tier_label: 'T3' }] as any,
      digimonPicks: [],
      dvp: { home: null, away: null },
      league: 'epl',
      cornerScoutData: { projection: 10.5, edge: 2.3, rating: 'STRONG BET' } as any,
    });

    expect(result.edgeBreakdown.weights).toEqual({ grok: 0.40, piff: 0.40, cornerScout: 0.20 });
    expect(result.edgeBreakdown.cornerScoutScore).toBeDefined();
  });

  it('does not drag the score toward 0.5 when PIFF is unavailable', () => {
    const result = calculateComposite({
      grokConfidence: 0.74,
      grokValueRating: 7,
      piffProps: [],
      digimonPicks: [],
      dvp: { home: null, away: null },
      league: 'mlb',
    });

    expect(result.compositeConfidence).toBe(0.74);
    expect(result.edgeBreakdown.weights).toEqual({ grok: 1, piff: 0, digimon: 0 });
  });

  it('redistributes soccer weights when corner data exists but PIFF does not', () => {
    const result = calculateComposite({
      grokConfidence: 0.66,
      grokValueRating: 6,
      piffProps: [],
      digimonPicks: [],
      dvp: { home: null, away: null },
      league: 'epl',
      cornerScoutData: { projection: 10.2, edge: 2.0, rating: 'LEAN' } as any,
    });

    expect(result.edgeBreakdown.weights).toEqual({ grok: 2 / 3, piff: 0, cornerScout: 1 / 3 });
    expect(result.compositeConfidence).toBeGreaterThan(0.66);
  });
});
