export type SessionConnectionState =
  | "idle"
  | "connecting"
  | "open"
  | "reconnecting"
  | "error";

export const CONNECTION_PING_INTERVAL_MS = 15_000;
export const CONNECTION_IDLE_TIMEOUT_MS = 45_000;
export const CONNECTION_WATCHDOG_INTERVAL_MS = 5_000;
export const RECONNECT_BASE_DELAY_MS = 1_000;
export const RECONNECT_MAX_DELAY_MS = 10_000;

export function getReconnectDelayMs(
  attempt: number,
  random: () => number = Math.random,
): number {
  const normalizedAttempt = Math.max(0, attempt);
  const baseDelay = Math.min(
    RECONNECT_MAX_DELAY_MS,
    RECONNECT_BASE_DELAY_MS * 2 ** normalizedAttempt,
  );
  const jitterMultiplier = 0.8 + random() * 0.4;
  return Math.round(baseDelay * jitterMultiplier);
}

export function isTerminalSocketClose(code?: number, reason?: string): boolean {
  return code === 1008 && /session not found|player not found/i.test(reason ?? "");
}

export function isConnectionStale(
  lastActivityAt: number | null | undefined,
  nowMs = Date.now(),
  timeoutMs = CONNECTION_IDLE_TIMEOUT_MS,
): boolean {
  if (!lastActivityAt) {
    return false;
  }
  return nowMs - lastActivityAt > timeoutMs;
}
