/**
 * Seeded RNG (mulberry32) for deterministic hatch results.
 * @param {number} seed
 * @returns {() => number}
 */
export function createSeededRng(seed) {
  let state = seed >>> 0;
  return function next() {
    state = (state + 0x6d2b79f5) >>> 0; // 32-bit
    let t = state;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

/**
 * @param {() => number} rng
 * @param {Array<{ id: string, weight: number }>} entries
 * @returns {string}
 */
export function pickId(rng, entries) {
  let total = 0;
  for (const e of entries) total += e.weight;
  if (total <= 0) throw new Error("WeightedRandom: non-positive total weight");
  const roll = rng() * total;
  let cumulative = 0;
  for (const e of entries) {
    cumulative += e.weight;
    if (roll < cumulative) return e.id;
  }
  return entries[entries.length - 1].id;
}
