import { describe, expect, it } from 'vitest';
import {
  BUMP_MOP_CHANCE,
  KAYDEN_HOLD_COOLDOWN_MS,
  KAYDEN_HOLD_MS,
  ORDER_LAG_MS,
  RADIO_COOLDOWN_MS,
  SHAN_CLEAN_CHANCE,
  SHAN_MIN_INTOX,
  orderLag,
  rollBumpMops,
  rollShanClean,
} from '../src/rules/staff';
import { drunkStage } from '../src/rules/drunk';
import { SeededRNG } from '../src/core/SeededRNG';
import { VENUES } from '../src/data/venues';

describe('radio command', () => {
  it('is a Head of Security-tier verb: Elevate and ROOM only', () => {
    expect(VENUES.map((v) => v.radioCommand === true)).toEqual([false, false, true, true]);
  });

  it('staff competence is real but imperfect — that IS the staff', () => {
    const rng = new SeededRNG(3).stream('s');
    let bump = 0;
    let shan = 0;
    for (let i = 0; i < 2000; i++) {
      if (rollBumpMops(rng)) bump++;
      if (rollShanClean(rng)) shan++;
    }
    expect(bump / 2000).toBeGreaterThan(BUMP_MOP_CHANCE - 0.05);
    expect(bump / 2000).toBeLessThan(BUMP_MOP_CHANCE + 0.05);
    expect(shan / 2000).toBeGreaterThan(SHAN_CLEAN_CHANCE - 0.05);
    expect(shan / 2000).toBeLessThan(SHAN_CLEAN_CHANCE + 0.05);
  });

  it('orders take a real walk and cool down longer than they take', () => {
    const rng = new SeededRNG(4).stream('s');
    for (let i = 0; i < 100; i++) {
      const lag = orderLag(rng);
      expect(lag).toBeGreaterThanOrEqual(ORDER_LAG_MS[0]);
      expect(lag).toBeLessThanOrEqual(ORDER_LAG_MS[1]);
    }
    expect(RADIO_COOLDOWN_MS.mess).toBeGreaterThan(ORDER_LAG_MS[1]);
    expect(RADIO_COOLDOWN_MS.water).toBeGreaterThan(ORDER_LAG_MS[1]);
  });

  it("Shan's floor starts at loose — sober people are not a radio matter", () => {
    expect(drunkStage(SHAN_MIN_INTOX)).toBe('loose');
  });

  it('the rope hold ends before it can be re-ordered', () => {
    expect(KAYDEN_HOLD_COOLDOWN_MS).toBeGreaterThan(KAYDEN_HOLD_MS);
  });
});
