// Hint-count derivation, kept out of the .svelte component so it is unit-testable.
//
// The badge shows the per-game hint allowance remaining plus the player's global hint wallet. The
// view's hints_remaining is the per-game allowance alone; the wallet is global (shared across every
// game) and read live from the profile (payments), never the per-game snapshot — so a wallet hint
// spent in another game stays reflected here.

import type { StateView } from './model';

/**
 * hintsLeft is the hint count for the badge: the per-game allowance remaining (view.hintsRemaining)
 * plus the live global wallet balance (passed in from the profile, so it stays correct when a wallet
 * hint was spent in another game since this view was fetched).
 */
export function hintsLeft(
  view: Pick<StateView, 'hintsRemaining'> | null,
  walletBalance: number,
): number {
  if (!view) return 0;
  return Math.max(0, view.hintsRemaining) + Math.max(0, walletBalance);
}

/** HINT_GATE_MS is the idle time a vs_ai player must be stuck on a turn before a hint unlocks. */
export const HINT_GATE_MS = 30 * 60 * 1000;

/**
 * hintGateRemainingMs returns how long (in milliseconds) until a vs_ai game's idle hint unlocks — 0
 * once it is available. It counts down from a MONOTONIC clock (performance.now()), so a client clock
 * change cannot skew it: gateStartMono is performance.now() captured when the source's "seconds left"
 * was received, gateLeftMs is that seconds-left in ms, and monoNow is performance.now() now; the
 * remaining is gateLeftMs minus the monotonic time elapsed since the anchor. gateStartMono null means
 * the gate is open (the human's first move, or a non-gated game). The duration comes from the source
 * (the SERVER clock online, the device clock offline) and is re-fetched on every load, so the wait
 * both persists across a relaunch and stays immune to a live clock change.
 */
export function hintGateRemainingMs(gateStartMono: number | null, gateLeftMs: number, monoNow: number): number {
  if (gateStartMono === null) return 0;
  return Math.max(0, gateLeftMs - (monoNow - gateStartMono));
}

/** hintLockMinutes rounds a remaining-milliseconds gap up to whole minutes for the "available in N
 *  min." toast, so a gate that is still closed never reads 0. */
export function hintLockMinutes(remainingMs: number): number {
  return Math.ceil(remainingMs / 60000);
}
