import crypto from "crypto";

export function generateCode(): string {
  return crypto.randomInt(0, 1_000_000).toString().padStart(6, "0");
}

export function hashCode(code: string, secret: string): string {
  return crypto.createHash("sha256").update(code + secret).digest("hex");
}

export type VerificationRowState = {
  codeHash: string | null;
  attempts: number;
  expires: Date;
};

export type CodeAttemptOutcome =
  | { outcome: "ok" }
  | { outcome: "wrong"; newAttempts: number }
  | { outcome: "locked-out" }
  | { outcome: "expired" }
  | { outcome: "no-such-row" };

const MAX_ATTEMPTS = 5;

export function evaluateCodeAttempt({
  submittedCodeHash,
  row,
  now,
}: {
  submittedCodeHash: string;
  row: VerificationRowState | null;
  now: Date;
}): CodeAttemptOutcome {
  if (!row) return { outcome: "no-such-row" };
  if (row.expires.getTime() <= now.getTime()) return { outcome: "expired" };
  if (row.attempts >= MAX_ATTEMPTS) return { outcome: "locked-out" };
  if (row.codeHash === submittedCodeHash) return { outcome: "ok" };

  const newAttempts = row.attempts + 1;
  if (newAttempts >= MAX_ATTEMPTS) return { outcome: "locked-out" };
  return { outcome: "wrong", newAttempts };
}
