'use strict';

const devig = require('../../src/utils/devig');

describe('de-vig engine (step 1)', () => {
  test('american → implied prob (favorite + dog + break-even)', () => {
    expect(devig.americanToImpliedProb(-110)).toBeCloseTo(0.5238, 3);
    expect(devig.americanToImpliedProb(+150)).toBeCloseTo(0.4, 3);
    expect(devig.americanToImpliedProb(+100)).toBeCloseTo(0.5, 3);
    expect(devig.americanToImpliedProb(0)).toBeNull();
    expect(devig.americanToImpliedProb(null)).toBeNull();
  });

  test('prob → fair american is the inverse', () => {
    expect(devig.impliedProbToAmerican(0.5)).toBe(100); // +100 at 50%
    expect(devig.impliedProbToAmerican(0.6)).toBe(-150);
    expect(devig.impliedProbToAmerican(0.4)).toBe(150);
    expect(devig.impliedProbToAmerican(0)).toBeNull();
    expect(devig.impliedProbToAmerican(1)).toBeNull();
  });

  test('two-way de-vig strips the vig; fair probs sum to 1', () => {
    // -110 / -110: each implies .5238, sum 1.0476 (4.76% vig) → fair .5 / .5
    const d = devig.devigTwoWay(-110, -110);
    expect(d.method).toBe('multiplicative');
    expect(d.overround).toBeCloseTo(0.048, 2);
    expect(d.over.fair_prob).toBeCloseTo(0.5, 3);
    expect(d.under.fair_prob).toBeCloseTo(0.5, 3);
    expect(d.over.fair_prob + d.under.fair_prob).toBeCloseTo(1, 6);
  });

  test('a juiced book price de-vigs to a fairer number (the story)', () => {
    // book -145 over vs +115 under
    const d = devig.devigTwoWay(-145, +115);
    expect(d.over.fair_prob + d.under.fair_prob).toBeCloseTo(1, 6);
    // the fair over price is less juiced than the -145 book price
    expect(d.over.fair_odds).toBeGreaterThan(-145);
  });

  test('only one side priced → fair UNAVAILABLE (never faked)', () => {
    expect(devig.devigTwoWay(-110, null)).toBeNull();
    expect(devig.devigTwoWay(null, -110)).toBeNull();
    expect(devig.devigTwoWay(undefined, undefined)).toBeNull();
  });

  test('EV% at the actual price from the model probability', () => {
    // model 55% on a +100 line: 0.55*2 - 1 = +10%
    expect(devig.evPct(0.55, +100)).toBeCloseTo(10, 1);
    // model 52.38% on -110 (= break-even): ~0 EV
    expect(devig.evPct(0.5238, -110)).toBeCloseTo(0, 0);
    // model 50% on -110 → negative (you pay the vig)
    expect(devig.evPct(0.5, -110)).toBeLessThan(0);
    expect(devig.evPct(null, -110)).toBeNull();
  });
});
