// The floor score (John's ask, 2026-07-21): the venue closes, the lights come
// ON, and the floor tells you what kind of night it was. Money, contraband,
// and objects with no explanation. Pure rolls here; the scene owns the sweep.

import type { RngStream } from '../core/SeededRNG';

export type DropKind = 'note' | 'coins' | 'baggie' | 'phone' | 'curio';

export interface Drop {
  kind: DropKind;
  /** Dollars. Curios and phones are worth nothing and everything. */
  value: number;
  label: string;
}

/** How strewn the floor is: a base mess plus one drop per this many admits. */
export const DROPS_BASE = 6;
export const DROPS_PER_ADMITS = 6;
export const DROPS_MAX = 14;

export const NOTE_VALUES: readonly number[] = [5, 5, 10, 10, 20, 50];
/** One baggie, sometimes. The moral beat of the sweep. */
export const BAGGIE_CHANCE = 0.35;
/** Someone's whole life, at 3%, face down near the booths. */
export const PHONE_CHANCE = 0.4;

export const CURIOS: readonly string[] = [
  'a single white sneaker. vintage, technically',
  'one hoop earring, lying there victorious',
  'an untouched kebab. UNTOUCHED.',
  'a novelty lighter shaped like a slightly smaller lighter',
  'seventeen bobby pins in one tight formation',
  "someone's nan's reading glasses",
  'a laminated business card. sovereign.',
  'a wristband from a venue that shut in 2019',
];

export const BAGGIE_LABEL = 'a zip-lock bag of definitely-not-yours';
export const PHONE_LABEL = "someone's phone. 3% battery. 41 missed calls from MUM DO NOT ANSWER";

/**
 * What the lights find. Deterministic per stream: mostly cash in anxious
 * denominations, a couple of objects with no explanation, at most one baggie
 * and one phone.
 */
export function rollDrops(rng: RngStream, admitted: number): Drop[] {
  const count = Math.min(DROPS_MAX, DROPS_BASE + Math.floor(admitted / DROPS_PER_ADMITS));
  const drops: Drop[] = [];

  if (rng.chance(BAGGIE_CHANCE)) drops.push({ kind: 'baggie', value: 0, label: BAGGIE_LABEL });
  if (rng.chance(PHONE_CHANCE)) drops.push({ kind: 'phone', value: 0, label: PHONE_LABEL });

  const curios = rng.int(2, 3);
  for (let i = 0; i < curios && drops.length < count; i++) {
    drops.push({ kind: 'curio', value: 0, label: CURIOS[rng.int(0, CURIOS.length - 1)] ?? CURIOS[0]! });
  }

  while (drops.length < count) {
    if (rng.chance(0.3)) {
      const v = rng.int(2, 9);
      drops.push({ kind: 'coins', value: v, label: `$${v} in shrapnel from under the booth seats` });
    } else {
      const v = NOTE_VALUES[rng.int(0, NOTE_VALUES.length - 1)] ?? 5;
      drops.push({ kind: 'note', value: v, label: `a folded $${v} — the floor pays better than the till` });
    }
  }
  return drops;
}
