import { createHash, randomBytes, randomUUID } from "node:crypto";

/**
 * Opaque single-use secrets (session cookies, confirmation links).
 *
 * Only the SHA-256 digest ever reaches the database. A dump of `sessions` or
 * `email_verification_tokens` therefore yields nothing replayable — the raw
 * value exists solely in the user's cookie jar or inbox.
 */

export interface IssuedToken {
  /** Goes into the cookie or the confirmation URL. Never persisted. */
  token: string;
  /** Primary key stored in the database. */
  hash: string;
}

export function issueToken(bytes = 32): IssuedToken {
  const token = randomBytes(bytes).toString("base64url");
  return { token, hash: hashToken(token) };
}

export function hashToken(token: string): string {
  return createHash("sha256").update(token).digest("hex");
}

/** Coarse client fingerprint for session bookkeeping — never a security control. */
export function hashIp(ip: string | null | undefined): string | null {
  if (!ip) return null;
  return createHash("sha256").update(ip).digest("hex").slice(0, 64);
}

export function newId(prefix: string): string {
  return `${prefix}_${randomUUID().replace(/-/g, "")}`.slice(0, 64);
}

/**
 * Re-exported here so Node-side callers (`session.ts`) only need one import
 * line. Lives in its own module (`bearer.ts`) because THIS file imports
 * `node:crypto`, which is not available wherever `bearerTokenFrom` is also
 * needed from the Edge runtime (`csrf.ts` / `middleware.ts`) — see that
 * file's header comment.
 */
export { bearerTokenFrom } from "./bearer";
