export type SessionStartOrigin = "unknown" | "remote" | "fresh-local" | "already-running-fallback"

interface ReconcileArgs {
  remoteStart: number
  localStart: number
  origin: SessionStartOrigin
}

interface ReconcileResult {
  localStart: number
  origin: SessionStartOrigin
}

/**
 * Reconcilia o início da sessão local com o timestamp vindo do servidor.
 * Mantém a proteção contra timestamps remotos defasados (que geravam tempo inflado),
 * mas permite substituir o fallback local quando sabemos que já existia uma sessão em andamento.
 */
export function reconcileLocalSessionStart({ remoteStart, localStart, origin }: ReconcileArgs): ReconcileResult {
  const sanitizedRemote = Number(remoteStart) || 0
  const sanitizedLocal = Number(localStart) || 0

  if (sanitizedRemote <= 0) {
    return { localStart: sanitizedLocal, origin }
  }

  if (sanitizedLocal <= 0) {
    return { localStart: sanitizedRemote, origin: "remote" }
  }

  if (sanitizedRemote >= sanitizedLocal) {
    return { localStart: sanitizedRemote, origin: "remote" }
  }

  if (origin === "already-running-fallback") {
    return { localStart: sanitizedRemote, origin: "remote" }
  }

  return { localStart: sanitizedLocal, origin }
}

interface OffsetArgs {
  currentOffset: number
  localNow: number
  serverNow?: number | null
}

/**
 * Calcula o deslocamento entre o relógio do navegador e o do servidor.
 * Usamos o menor número de suposições possível: basta termos uma leitura de serverNow
 * para alinhar o relógio local.
 */
export function deriveServerOffset({ currentOffset, localNow, serverNow }: OffsetArgs): number {
  if (typeof serverNow !== "number" || Number.isNaN(serverNow)) {
    return currentOffset
  }
  const nextOffset = localNow - serverNow
  if (!Number.isFinite(nextOffset)) {
    return currentOffset
  }
  if (!Number.isFinite(currentOffset) || currentOffset === 0) {
    return nextOffset
  }
  const MAX_REASONABLE_JUMP = 5 * 60 * 1000 // 5 minutos
  if (Math.abs(nextOffset - currentOffset) > MAX_REASONABLE_JUMP) {
    return nextOffset
  }
  return nextOffset
}

export function toServerTimestamp(localNow: number, offset: number): number {
  if (!Number.isFinite(localNow)) return localNow
  if (!Number.isFinite(offset)) return localNow
  return localNow - offset
}
