import { describe, expect, it } from 'vitest';
import {
  DROPS_BASE,
  DROPS_MAX,
  NOTE_VALUES,
  rollDrops,
} from '../src/rules/floorScore';
import { SeededRNG } from '../src/core/SeededRNG';

describe('the floor score', () => {
  it('a busier night is a messier floor, up to a limit', () => {
    const rng = new SeededRNG(1);
    expect(rollDrops(rng.stream('a'), 0).length).toBe(DROPS_BASE);
    expect(rollDrops(rng.stream('b'), 24).length).toBe(DROPS_BASE + 4);
    expect(rollDrops(rng.stream('c'), 500).length).toBe(DROPS_MAX);
  });

  it('is deterministic per stream — the same night drops the same floor', () => {
    const a = rollDrops(new SeededRNG(7).stream('sweep'), 40);
    const b = rollDrops(new SeededRNG(7).stream('sweep'), 40);
    expect(a).toEqual(b);
  });

  it('cash is real denominations; curios, phones and baggies are worth $0', () => {
    for (let seed = 1; seed <= 20; seed++) {
      for (const d of rollDrops(new SeededRNG(seed).stream('s'), 60)) {
        if (d.kind === 'note') expect(NOTE_VALUES).toContain(d.value);
        else if (d.kind === 'coins') expect(d.value).toBeGreaterThan(0);
        else expect(d.value).toBe(0);
      }
    }
  });

  it('at most one baggie and one phone per night', () => {
    for (let seed = 1; seed <= 30; seed++) {
      const drops = rollDrops(new SeededRNG(seed).stream('s'), 60);
      expect(drops.filter((d) => d.kind === 'baggie').length).toBeLessThanOrEqual(1);
      expect(drops.filter((d) => d.kind === 'phone').length).toBeLessThanOrEqual(1);
    }
  });

  it('every drop has words — the label IS the reward for curios', () => {
    for (const d of rollDrops(new SeededRNG(11).stream('s'), 30)) {
      expect(d.label.length).toBeGreaterThan(5);
    }
  });
});
