import { describe, expect, it } from 'vitest';
import {
  AID_STEPS,
  FAINT_WINDOW,
  MOP_MS,
  SLIP_CHANCE_PER_S,
  WATER_SOBER_STEP,
  slipChance,
  watered,
} from '../../src/scenes/floor/hazards';
import { drunkStage } from '../../src/rules/drunk';

describe('slipChance', () => {
  it('a signed puddle never slips anyone — that is what the sign is', () => {
    expect(slipChance(true, 16)).toBe(0);
    expect(slipChance(true, 100000)).toBe(0);
  });

  it('an unsigned puddle scales with dt and clamps at certainty', () => {
    expect(slipChance(false, 1000)).toBeCloseTo(SLIP_CHANCE_PER_S);
    expect(slipChance(false, 500)).toBeCloseTo(SLIP_CHANCE_PER_S / 2);
    expect(slipChance(false, 1e9)).toBe(1);
  });
});

describe('watered', () => {
  it('takes one step off and floors at zero', () => {
    expect(watered(0.5)).toBeCloseTo(0.5 - WATER_SOBER_STEP);
    expect(watered(0.02)).toBe(0);
  });

  it('is real but not a cure: one cup cannot un-maggot anyone', () => {
    // The bottom of the maggot band, watered, must still be a serious problem —
    // the duty pays at 'loose', not at the point of no return.
    let maggotFloor = 1;
    for (let v = 0; v <= 1; v += 0.001) {
      if (drunkStage(v) === 'maggot') {
        maggotFloor = v;
        break;
      }
    }
    const after = drunkStage(watered(maggotFloor));
    expect(after === 'messy' || after === 'maggot').toBe(true);
  });
});

describe('the fainter', () => {
  it('has plain, unfunny steps with generous windows', () => {
    expect(AID_STEPS.length).toBe(3);
    for (const s of AID_STEPS) {
      expect(s.ms).toBeGreaterThanOrEqual(4000);
      expect(s.label).toBe(s.label.toLowerCase()); // no bits, no shouting
      expect(s.label).not.toMatch(/!|\?/);
    }
  });

  it('lands inside the night', () => {
    expect(FAINT_WINDOW[0]).toBeGreaterThan(0);
    expect(FAINT_WINDOW[1]).toBeLessThanOrEqual(350);
  });
});

describe('mopping', () => {
  it('is a real commitment, not a tap', () => {
    expect(MOP_MS).toBeGreaterThanOrEqual(1500);
  });
});
