// Local game id helpers, in a tiny standalone module with no engine/generator imports, so the
// dispatcher (lib/gamesource) can recognise a local game id — and the game screen can branch on it
// — without eagerly bundling the whole offline engine. The engine is dynamically imported only when
// a local game is actually played (keeping the app entry bundle within its size budget).

/** LOCAL_ID_PREFIX marks a game id as a local (offline) game. */
export const LOCAL_ID_PREFIX = 'local:';

/** isLocalGameId reports whether an id belongs to a local game. */
export function isLocalGameId(id: string): boolean {
  return id.startsWith(LOCAL_ID_PREFIX);
}

/** newLocalGameId mints a fresh, device-unique local game id (time + random suffix — no crypto API,
 *  so it also works on the older engines the SPA still supports). */
export function newLocalGameId(): string {
  return `${LOCAL_ID_PREFIX}${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
}

// A test seam for the mock e2e: pinning the seed makes a local game deal a known rack, so a spec
// can play a precomputed opening word. Only the mock build's window.__mock wires setForcedSeed
// (see lib/gateway.ts); a production build never calls it, so randomSeed stays truly random.
let forcedSeed: bigint | null = null;

/** setForcedSeed pins the value randomSeed returns (the mock-e2e seam); pass null to restore
 *  randomness. */
export function setForcedSeed(seed: bigint | null): void {
  forcedSeed = seed;
}

/** randomSeed returns a random 32-bit seed for a new local game's deterministic bag (or the pinned
 *  seed when a test has set one via setForcedSeed). */
export function randomSeed(): bigint {
  if (forcedSeed !== null) return forcedSeed;
  return BigInt(Math.floor(Math.random() * 0xffffffff));
}
