import { hashPassword, verifyPassword } from "@wrnexus/core";
import type { OAuthProfile, OAuthTokens } from "@wrnexus/oauth";
import {
  constantTimeEqual,
  fingerprint,
  hashSecret,
  randomDigits,
  randomReadableCode,
  randomToken,
} from "./crypto.ts";
import { inferIdentityType, normalizeIdentity, publicUser } from "./normalize.ts";
import { assertPasskeyProvider, MemoryPasskeyChallengeStore } from "./passkeys/index.ts";
import { evaluateAuthRisk } from "./risk.ts";
import type { AuthStore } from "./store.ts";
import { generateTotpSecret, totpUri, verifyTotp } from "./totp/index.ts";
import type {
  AuthDeliveryMessage,
  AuthEngineOptions,
  AuthIdentity,
  AuthIdentityType,
  AuthResult,
  AuthSecurityEvent,
  AuthSession,
  AuthSignedInHandler,
  AuthSignedOutHandler,
  AuthSuccessfulSignUpHandler,
  AuthTokenPurpose,
  AuthUser,
  LoginInput,
  OAuthAccount,
  PasskeyAuthenticationOptions,
  PasskeyRegistrationOptions,
  RegisterInput,
  TrustedDevice,
} from "./types.ts";

const MIN_SECRET_LENGTH = 32;
const DEFAULT_TOKEN_TTLS: Record<AuthTokenPurpose, number> = {
  "verify-email": 24 * 60 * 60_000,
  "verify-phone": 15 * 60_000,
  "password-reset": 30 * 60_000,
  "magic-link": 15 * 60_000,
  invite: 7 * 24 * 60 * 60_000,
  "change-email": 30 * 60_000,
  "change-phone": 15 * 60_000,
  "login-mfa": 5 * 60_000,
};

export interface AuthEngine {
  readonly store: AuthStore;
  readonly onSignedIn?: AuthSignedInHandler;
  readonly onSignedOut?: AuthSignedOutHandler;
  readonly onSuccessfulSignUp?: AuthSuccessfulSignUpHandler;
  register(input: RegisterInput): Promise<AuthResult>;
  login(input: LoginInput): Promise<AuthResult>;
  logout(sessionId: string, reason?: string): Promise<void>;
  findUserByIdentifier(identifier: string): Promise<AuthUser | undefined>;
  getUser(userId: string): Promise<AuthUser | undefined>;
  getPublicUser(userId: string): Promise<ReturnType<typeof publicUser> | undefined>;
  createSession(
    userId: string,
    input?: Partial<AuthSession> & { fingerprint?: string; deviceName?: string },
  ): Promise<AuthSession>;
  validateSession(sessionId: string): Promise<AuthSession | undefined>;
  listSessions(userId: string): Promise<AuthSession[]>;
  revokeSession(userId: string, sessionId: string, reason?: string): Promise<boolean>;
  revokeAllSessions(userId: string, exceptSessionId?: string, reason?: string): Promise<number>;
  trustDevice(
    userId: string,
    input: { fingerprint: string; name?: string },
  ): Promise<TrustedDevice>;
  listTrustedDevices(userId: string): ReturnType<AuthStore["listTrustedDevices"]>;
  revokeTrustedDevice(userId: string, deviceId: string): Promise<boolean>;
  issueToken(
    userId: string,
    purpose: AuthTokenPurpose,
    input?: { target?: string; metadata?: Record<string, unknown>; ttlMs?: number },
  ): Promise<string>;
  consumeToken(token: string, purpose: AuthTokenPurpose): Promise<AuthUser | undefined>;
  verifyEmail(token: string): Promise<AuthResult>;
  verifyPhone(token: string): Promise<AuthResult>;
  requestVerification(userId: string, type: "email" | "phone", baseUrl?: string): Promise<void>;
  requestPasswordReset(identifier: string, baseUrl?: string): Promise<void>;
  resetPassword(token: string, password: string): Promise<AuthResult>;
  requestMagicLink(identifier: string, baseUrl?: string): Promise<void>;
  createInvitation(input: {
    email: string;
    displayName?: string;
    roles?: string[];
    invitedBy?: string;
    metadata?: Record<string, unknown>;
    ttlMs?: number;
    baseUrl?: string;
  }): Promise<{ token: string; user: ReturnType<typeof publicUser> }>;
  acceptInvitation(
    token: string,
    input: { password?: string; displayName?: string },
  ): Promise<AuthResult>;
  consumeMagicLink(token: string, sessionInput?: Partial<AuthSession>): Promise<AuthResult>;
  issueOtp(
    userId: string,
    method: "email-otp" | "sms-otp",
    destination?: string,
    purpose?: "verification" | "login" | "mfa",
  ): Promise<{ id: string; expiresAt: number }>;
  verifyOtp(
    challengeId: string,
    code: string,
    expectedPurpose?: "verification" | "login" | "mfa",
  ): Promise<AuthResult>;
  requestOtpLogin(
    identifier: string,
    method: "email-otp" | "sms-otp",
  ): Promise<{ id: string; expiresAt: number }>;
  completeOtpLogin(
    challengeId: string,
    code: string,
    sessionInput?: Partial<AuthSession>,
  ): Promise<AuthResult>;
  beginMfaOtp(
    mfaToken: string,
    method: "email-otp" | "sms-otp",
  ): Promise<{ id: string; expiresAt: number } | undefined>;
  completeMfa(input: {
    mfaToken: string;
    method: "totp" | "recovery-code" | "email-otp" | "sms-otp";
    code: string;
    challengeId?: string;
    session?: Partial<AuthSession>;
  }): Promise<AuthResult>;
  beginTotp(
    userId: string,
    label?: string,
  ): Promise<{ credentialId: string; secret: string; uri: string }>;
  confirmTotp(userId: string, credentialId: string, token: string): Promise<boolean>;
  verifyTotp(userId: string, token: string): Promise<boolean>;
  disableTotp(userId: string, credentialId: string): Promise<boolean>;
  generateRecoveryCodes(userId: string, count?: number): Promise<string[]>;
  consumeRecoveryCode(userId: string, code: string): Promise<boolean>;
  listRecoveryCodeStatus(userId: string): Promise<{ total: number; remaining: number }>;
  linkOAuth(
    userId: string,
    provider: string,
    profile: OAuthProfile,
    tokens?: OAuthTokens,
  ): Promise<OAuthAccount>;
  loginWithOAuth(
    provider: string,
    profile: OAuthProfile,
    tokens?: OAuthTokens,
  ): Promise<AuthResult>;
  unlinkOAuth(userId: string, accountId: string): Promise<boolean>;
  beginPasskeyRegistration(
    userId: string,
    input: { rpId: string; rpName: string; origin: string },
  ): Promise<{ key: string; options: PasskeyRegistrationOptions }>;
  finishPasskeyRegistration(
    userId: string,
    input: {
      key: string;
      response: unknown;
      name?: string;
      /** @deprecated Verification uses the RP ID bound to the issued challenge. */
      rpId?: string;
      /** @deprecated Verification uses the origin bound to the issued challenge. */
      origin?: string;
    },
  ): Promise<boolean>;
  beginPasskeyAuthentication(input: {
    identifier?: string;
    rpId: string;
    origin: string;
  }): Promise<{ key: string; options: PasskeyAuthenticationOptions }>;
  finishPasskeyAuthentication(input: {
    key: string;
    response: unknown;
    /** Request metadata used only for the resulting session. */
    session?: Partial<AuthSession>;
    /** @deprecated Verification uses the RP ID bound to the issued challenge. */
    rpId?: string;
    /** @deprecated Verification uses the origin bound to the issued challenge. */
    origin?: string;
  }): Promise<AuthResult>;
  changePassword(
    userId: string,
    currentPassword: string,
    nextPassword: string,
  ): Promise<AuthResult>;
  setAccountStatus(userId: string, status: AuthUser["status"], actorUserId?: string): Promise<void>;
  startImpersonation(
    actorUserId: string,
    targetUserId: string,
    input?: { reason?: string; sessionId?: string; ip?: string; userAgent?: string },
  ): Promise<AuthResult>;
  stopImpersonation(sessionId: string): Promise<AuthResult>;
}

function defaultRandom(length: number): Uint8Array {
  return crypto.getRandomValues(new Uint8Array(length));
}

function safeIdentifier(value: string): string {
  const trimmed = value.trim().slice(0, 320);
  return normalizeIdentity(inferIdentityType(trimmed), trimmed);
}

function normalizedOAuthProvider(value: string): string {
  const provider = value.trim().toLowerCase();
  if (!provider || provider.length > 64 || !/^[a-z0-9._-]+$/.test(provider)) {
    throw new TypeError(
      "OAuth provider must use 1 to 64 letters, numbers, dots, underscores, or hyphens",
    );
  }
  return provider;
}

function normalizedOAuthAccountId(value: string): string {
  const accountId = value.trim();
  if (!accountId || accountId.length > 191) {
    throw new TypeError("OAuth provider account ID must contain 1 to 191 characters");
  }
  return accountId;
}

function validatedIdentity(type: AuthIdentityType, value: string): string {
  const raw = value.trim();
  const normalized = normalizeIdentity(type, raw);
  if (type === "email") {
    if (raw.length > 320 || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(raw)) {
      throw new TypeError("Enter a valid email address");
    }
  } else if (type === "phone") {
    if (raw.length > 24 || !/^\+?[0-9 ()-]{7,24}$/.test(raw) || !/^\+?\d{7,15}$/.test(normalized)) {
      throw new TypeError("Enter a valid phone number");
    }
  } else if (
    normalized.length < 3 ||
    normalized.length > 64 ||
    !/^[a-z0-9._-]+$/.test(normalized)
  ) {
    throw new TypeError("Enter a valid username");
  }
  return normalized;
}

function positiveInteger(
  value: number | undefined,
  fallback: number,
  name: string,
  minimum = 1,
): number {
  const resolved = value ?? fallback;
  if (!Number.isSafeInteger(resolved) || resolved < minimum) {
    throw new TypeError(`${name} must be a safe integer greater than or equal to ${minimum}`);
  }
  return resolved;
}

function positiveDuration(value: number | undefined, fallback: number, name: string): number {
  const resolved = value ?? fallback;
  if (!Number.isFinite(resolved) || resolved <= 0) {
    throw new TypeError(`${name} must be a positive finite duration`);
  }
  return Math.trunc(resolved);
}

function passkeyChallengeTtl(timeout: number): number {
  const fallback = 5 * 60_000;
  if (!Number.isFinite(timeout)) return fallback;
  return Math.min(10 * 60_000, Math.max(30_000, Math.trunc(timeout)));
}

export function createAuthEngine(options: AuthEngineOptions): AuthEngine {
  if (options.secret.length < MIN_SECRET_LENGTH) {
    throw new TypeError(`auth secret must be at least ${MIN_SECRET_LENGTH} characters`);
  }
  const store = options.store;
  const now = () => {
    const value = options.clock?.now() ?? Date.now();
    if (!Number.isFinite(value)) throw new Error("WRN-AUTH-CLOCK: clock returned an invalid time");
    return Math.trunc(value);
  };
  const random = (length: number) => options.random?.bytes(length) ?? defaultRandom(length);
  const issuer = options.issuer?.trim() || "WRNexusJS";
  const sessionTtlMs = positiveDuration(options.sessionTtlMs, 24 * 60 * 60_000, "sessionTtlMs");
  const absoluteTtlMs = positiveDuration(
    options.sessionAbsoluteTtlMs,
    30 * 24 * 60 * 60_000,
    "sessionAbsoluteTtlMs",
  );
  if (absoluteTtlMs < sessionTtlMs) {
    throw new TypeError("sessionAbsoluteTtlMs must be greater than or equal to sessionTtlMs");
  }
  const trustedTtlMs = positiveDuration(
    options.trustedDeviceTtlMs,
    90 * 24 * 60 * 60_000,
    "trustedDeviceTtlMs",
  );
  const otpTtlMs = positiveDuration(options.otpTtlMs, 10 * 60_000, "otpTtlMs");
  const maxTokenAttempts = positiveInteger(options.maxTokenAttempts, 5, "maxTokenAttempts");
  const maxOtpAttempts = positiveInteger(options.maxOtpAttempts, 5, "maxOtpAttempts");
  const maxFailedLogins = positiveInteger(options.maxFailedLogins, 5, "maxFailedLogins");
  const lockDurationMs = positiveDuration(options.lockDurationMs, 15 * 60_000, "lockDurationMs");
  const passwordMinLength = positiveInteger(options.passwordMinLength, 12, "passwordMinLength", 8);
  const passkeyChallenges = options.passkeyChallengeStore ?? new MemoryPasskeyChallengeStore(now);
  let dummyPasswordHash: Promise<string> | undefined;
  const protect = async (value: string, purpose: "totp" | "oauth-access" | "oauth-refresh") =>
    options.secretProtector ? options.secretProtector.protect(value, purpose) : value;
  const reveal = async (value: string, purpose: "totp" | "oauth-access" | "oauth-refresh") =>
    options.secretProtector ? options.secretProtector.reveal(value, purpose) : value;

  const id = (prefix: string) => `${prefix}_${randomToken(random, 18)}`;
  const tokenTtl = (purpose: AuthTokenPurpose, override?: number) =>
    positiveDuration(
      override ?? options.tokenTtlMs?.[purpose],
      DEFAULT_TOKEN_TTLS[purpose],
      `tokenTtlMs.${purpose}`,
    );

  async function audit(input: Omit<AuthSecurityEvent, "id" | "createdAt">): Promise<void> {
    const event: AuthSecurityEvent = { ...input, id: id("evt"), createdAt: now() };
    await store.createSecurityEvent(event);
    await options.audit?.(event);
  }

  async function deliver(message: AuthDeliveryMessage): Promise<boolean> {
    if (!options.delivery) return false;
    try {
      await options.delivery.send(message);
      return true;
    } catch (error) {
      await audit({
        userId: message.user.id,
        type: "delivery.failed",
        severity: "warning",
        data: {
          channel: message.channel,
          template: message.template,
          error: error instanceof Error ? error.name : "UnknownError",
        },
      });
      return false;
    }
  }

  async function findUserByIdentifier(identifier: string): Promise<AuthUser | undefined> {
    const type = inferIdentityType(identifier);
    const identity = await store.findIdentity(type, normalizeIdentity(type, identifier));
    return identity ? store.findUserById(identity.userId) : undefined;
  }

  async function restoreExpiredLoginLock(user: AuthUser): Promise<void> {
    if (user.status !== "locked") return;
    const metadata = user.metadata ?? {};
    const lockedUntil = Number(metadata.lockedUntil ?? 0);
    if (
      metadata.lockReason !== "failed-login" ||
      !Number.isFinite(lockedUntil) ||
      lockedUntil <= 0 ||
      lockedUntil > now()
    ) {
      return;
    }
    const previous = metadata.lockedPreviousStatus === "pending" ? "pending" : "active";
    const {
      lockedUntil: _lockedUntil,
      lockReason: _lockReason,
      lockedPreviousStatus: _previous,
      ...rest
    } = metadata;
    user.status = previous;
    user.metadata = Object.keys(rest).length ? rest : undefined;
    user.updatedAt = now();
    await store.updateUser(user);
  }

  function accountStatusUnavailable(user: AuthUser): AuthResult | undefined {
    if (user.status === "locked") {
      return {
        ok: false,
        code: "account-locked",
        message: "This account is locked. Try again later or contact support.",
      };
    }
    if (user.status === "disabled") {
      return {
        ok: false,
        code: "account-disabled",
        message: "This account is disabled. Contact support for help.",
      };
    }
    if (user.status === "deleted") {
      return {
        ok: false,
        code: "account-deleted",
        message: "This account is unavailable. Contact support for help.",
      };
    }
    return undefined;
  }

  function recoveryUnavailable(user: AuthUser): AuthResult | undefined {
    if (user.status === "disabled" || user.status === "deleted") {
      return {
        ok: false,
        code: `account-${user.status}`,
        message: "This account cannot complete recovery",
      };
    }
    if (user.status === "locked" && user.metadata?.lockReason !== "failed-login") {
      return {
        ok: false,
        code: "account-locked",
        message: "This account cannot complete recovery",
      };
    }
    return undefined;
  }

  async function clearFailedLoginLock(user: AuthUser): Promise<void> {
    if (user.status !== "locked" || user.metadata?.lockReason !== "failed-login") return;
    const metadata = user.metadata ?? {};
    const previous = metadata.lockedPreviousStatus === "pending" ? "pending" : "active";
    const {
      lockedUntil: _lockedUntil,
      lockReason: _lockReason,
      lockedPreviousStatus: _previous,
      ...rest
    } = metadata;
    user.status = previous;
    user.metadata = Object.keys(rest).length ? rest : undefined;
    user.updatedAt = now();
    await store.updateUser(user);
  }

  function verificationUnavailable(user: AuthUser): AuthResult | undefined {
    if (options.requireVerifiedEmail && !user.emailVerified) {
      return {
        ok: false,
        code: "email-unverified",
        message: "Verify your email address before signing in.",
        user: publicUser(user),
        requires: { emailVerification: true },
      };
    }
    if (options.requireVerifiedPhone && !user.phoneVerified) {
      return {
        ok: false,
        code: "phone-unverified",
        message: "Verify your phone number before signing in.",
        user: publicUser(user),
        requires: { phoneVerification: true },
      };
    }
    return undefined;
  }

  async function mfaRequirement(
    user: AuthUser,
    metadata: Record<string, unknown> = {},
  ): Promise<AuthResult | undefined> {
    if (!(await hasMfa(user.id))) return undefined;
    const methods = await availableMfaMethods(user.id);
    if (!methods.length) {
      return {
        ok: false,
        code: "mfa-unavailable",
        message: "Additional verification is required but no verification method is available",
      };
    }
    const mfaToken = await issueToken(user.id, "login-mfa", {
      ttlMs: 5 * 60_000,
      metadata,
    });
    return {
      ok: false,
      code: "mfa-required",
      message: "Complete two-step verification to finish signing in.",
      user: publicUser(user),
      mfaToken,
      requires: { mfa: methods },
    };
  }

  async function assertPasswordPolicy(password: string): Promise<void> {
    if (password.length < passwordMinLength) {
      throw new Error(`Password must be at least ${passwordMinLength} characters`);
    }
    if (!/[a-z]/.test(password) || !/[A-Z]/.test(password) || !/\d/.test(password)) {
      throw new Error("Password must include uppercase, lowercase, and a number");
    }
    if (await options.breachProvider?.isBreached(password)) {
      throw new Error("This password appears in a known breach");
    }
  }

  async function consumeUnknownPasswordAttempt(password: string): Promise<void> {
    dummyPasswordHash ??= hashPassword(`WRNexusJS-Dummy-${randomToken(random, 24)}-Aa1`);
    await verifyPassword(password, await dummyPasswordHash);
  }

  async function createIdentity(
    userId: string,
    type: AuthIdentityType,
    value: string,
    primary: boolean,
  ): Promise<AuthIdentity> {
    const normalizedValue = validatedIdentity(type, value);
    if (await store.findIdentity(type, normalizedValue)) {
      throw new Error(`${type} is already in use`);
    }
    const timestamp = now();
    const identity: AuthIdentity = {
      id: id("idn"),
      userId,
      type,
      value: value.trim(),
      normalizedValue,
      primary,
      createdAt: timestamp,
      updatedAt: timestamp,
    };
    await store.createIdentity(identity);
    return identity;
  }

  async function issueToken(
    userId: string,
    purpose: AuthTokenPurpose,
    input: { target?: string; metadata?: Record<string, unknown>; ttlMs?: number } = {},
  ): Promise<string> {
    if (!(await store.findUserById(userId))) throw new Error("User not found");
    const raw = randomToken(random, 32);
    const timestamp = now();
    await store.createToken({
      id: id("tok"),
      userId,
      purpose,
      tokenHash: await hashSecret(raw, options.secret),
      target: input.target,
      createdAt: timestamp,
      expiresAt: timestamp + tokenTtl(purpose, input.ttlMs),
      attempts: 0,
      maxAttempts: maxTokenAttempts,
      metadata: input.metadata,
    });
    return raw;
  }

  async function consumeTokenRecord(
    raw: string,
    purpose: AuthTokenPurpose,
  ): Promise<{ user: AuthUser; token: import("./types.ts").OneTimeToken } | undefined> {
    const token = await store.findTokenByHash(await hashSecret(raw, options.secret));
    if (!token || token.purpose !== purpose || token.usedAt || token.expiresAt <= now())
      return undefined;
    token.attempts += 1;
    if (token.attempts > token.maxAttempts) {
      await store.updateToken(token);
      return undefined;
    }
    const user = await store.findUserById(token.userId);
    if (!user) return undefined;
    token.usedAt = now();
    await store.updateToken(token);
    return { user, token };
  }

  async function consumeToken(
    raw: string,
    purpose: AuthTokenPurpose,
  ): Promise<AuthUser | undefined> {
    return (await consumeTokenRecord(raw, purpose))?.user;
  }

  async function inspectToken(raw: string, purpose: AuthTokenPurpose) {
    const token = await store.findTokenByHash(await hashSecret(raw, options.secret));
    if (!token || token.purpose !== purpose || token.usedAt || token.expiresAt <= now())
      return undefined;
    return token;
  }

  async function consumeInspectedToken(token: import("./types.ts").OneTimeToken): Promise<void> {
    token.attempts += 1;
    token.usedAt = now();
    await store.updateToken(token);
  }

  function actionUrl(
    user: AuthUser,
    purpose: AuthTokenPurpose,
    token: string,
    destination: string,
    baseUrl?: string,
  ): string | undefined {
    if (options.tokenUrl) {
      return options.tokenUrl({
        purpose,
        token,
        baseUrl,
        destination,
        user: publicUser(user),
      });
    }
    if (!baseUrl) return undefined;
    if (purpose === "invite") {
      return new URL(`/join/${encodeURIComponent(token)}`, baseUrl).toString();
    }
    return new URL(`/${purpose}?token=${encodeURIComponent(token)}`, baseUrl).toString();
  }

  async function sendToken(
    user: AuthUser,
    purpose: AuthTokenPurpose,
    destination: string,
    baseUrl?: string,
  ): Promise<string> {
    const token = await issueToken(user.id, purpose, { target: destination });
    const url = actionUrl(user, purpose, token, destination, baseUrl);
    await deliver({
      channel: destination.includes("@") ? "email" : "sms",
      template:
        purpose === "password-reset"
          ? "password-reset"
          : purpose === "magic-link"
            ? "magic-link"
            : purpose === "verify-email"
              ? "verify-email"
              : purpose === "invite"
                ? "invitation"
                : "verify-phone",
      destination,
      token,
      url,
      user: publicUser(user),
      expiresAt: now() + tokenTtl(purpose),
    });
    return token;
  }

  async function sendLoginAlert(user: AuthUser, session: AuthSession): Promise<void> {
    if (!options.sendLoginAlerts || !options.delivery) return;
    const identities = await store.listIdentities(user.id);
    const destination =
      identities.find((item) => item.type === "email" && item.primary)?.value ??
      identities.find((item) => item.type === "email")?.value;
    if (!destination) return;
    await deliver({
      channel: "email",
      template: "login-alert",
      destination,
      user: publicUser(user),
      expiresAt: session.expiresAt,
      data: {
        sessionId: session.id,
        deviceId: session.deviceId,
        ip: session.ip,
        userAgent: session.userAgent,
        createdAt: session.createdAt,
      },
    });
  }

  async function createSession(
    userId: string,
    input: Partial<AuthSession> & { fingerprint?: string; deviceName?: string } = {},
  ): Promise<AuthSession> {
    if (!(await store.findUserById(userId))) throw new Error("User not found");
    const timestamp = now();
    let trusted = Boolean(input.trusted);
    let deviceId = input.deviceId ?? id("dev");
    if (input.fingerprint) {
      const hash = await fingerprint(input.fingerprint);
      const existing = await store.findTrustedDeviceByFingerprint(userId, hash);
      if (existing && !existing.revokedAt && existing.expiresAt > timestamp) {
        trusted = true;
        deviceId = existing.id;
        existing.lastSeenAt = timestamp;
        await store.updateTrustedDevice(existing);
      }
    }
    const session: AuthSession = {
      id: input.id ?? id("ses"),
      userId,
      deviceId,
      createdAt: timestamp,
      lastSeenAt: timestamp,
      expiresAt: timestamp + sessionTtlMs,
      absoluteExpiresAt: timestamp + absoluteTtlMs,
      ip: input.ip,
      userAgent: input.userAgent,
      trusted,
      metadata: input.metadata,
    };
    await store.createSession(session);
    return session;
  }

  async function validateSession(sessionId: string): Promise<AuthSession | undefined> {
    const session = await store.findSession(sessionId);
    const timestamp = now();
    if (
      !session ||
      session.revokedAt ||
      session.expiresAt <= timestamp ||
      session.absoluteExpiresAt <= timestamp
    ) {
      if (session) await store.deleteSession(session.id);
      return undefined;
    }
    session.lastSeenAt = timestamp;
    session.expiresAt = Math.min(timestamp + sessionTtlMs, session.absoluteExpiresAt);
    await store.updateSession(session);
    return session;
  }

  async function markVerified(
    user: AuthUser,
    type: "email" | "phone",
    targetValue?: string,
  ): Promise<boolean> {
    const identities = await store.listIdentities(user.id);
    const normalizedTarget = targetValue ? normalizeIdentity(type, targetValue) : undefined;
    const target = normalizedTarget
      ? identities.find((item) => item.type === type && item.normalizedValue === normalizedTarget)
      : (identities.find((item) => item.type === type && item.primary) ??
        identities.find((item) => item.type === type));
    if (!target) return false;
    target.verifiedAt = now();
    target.updatedAt = now();
    await store.updateIdentity(target);
    if (type === "email") user.emailVerified = true;
    else user.phoneVerified = true;
    if (user.status === "pending") user.status = "active";
    user.updatedAt = now();
    await store.updateUser(user);
    return true;
  }

  async function issueOtp(
    userId: string,
    method: "email-otp" | "sms-otp",
    destination?: string,
    purpose: "verification" | "login" | "mfa" = "verification",
  ) {
    const user = await store.findUserById(userId);
    if (!user) throw new Error("User not found");
    const identities = await store.listIdentities(userId);
    const type = method === "email-otp" ? "email" : "phone";
    const matchingIdentities = identities.filter(
      (item) => item.type === type && (purpose !== "mfa" || Boolean(item.verifiedAt)),
    );
    const normalizedDestination = destination ? normalizeIdentity(type, destination) : undefined;
    const requestedIdentity = normalizedDestination
      ? matchingIdentities.find((item) => item.normalizedValue === normalizedDestination)
      : undefined;
    if (destination && !requestedIdentity) {
      throw new Error(`OTP destination must be a linked ${type} identity`);
    }
    const resolved =
      requestedIdentity?.value ??
      matchingIdentities.find((item) => item.primary)?.value ??
      matchingIdentities[0]?.value;
    if (!resolved) throw new Error(`No ${type} identity is available`);
    const code = randomDigits(random, 6);
    const timestamp = now();
    const challenge = {
      id: id("otp"),
      userId,
      method,
      purpose,
      destination: resolved,
      codeHash: await hashSecret(code, options.secret),
      createdAt: timestamp,
      expiresAt: timestamp + otpTtlMs,
      attempts: 0,
      maxAttempts: maxOtpAttempts,
    } as const;
    await store.createOtp(challenge);
    await deliver({
      channel: method === "email-otp" ? "email" : "sms",
      template: method,
      destination: resolved,
      code,
      user: publicUser(user),
      expiresAt: challenge.expiresAt,
    });
    return { id: challenge.id, expiresAt: challenge.expiresAt };
  }

  async function oauthEmailVerified(provider: string, profile: OAuthProfile): Promise<boolean> {
    if (!profile.email) return false;
    if (options.isOAuthEmailVerified) return options.isOAuthEmailVerified(provider, profile);
    const raw = profile.raw;
    return (
      raw.email_verified === true ||
      raw.verified_email === true ||
      raw.emailVerified === true ||
      raw.verified === true
    );
  }

  async function hasMfa(userId: string): Promise<boolean> {
    const [totp, recovery] = await Promise.all([
      store.listTotp(userId),
      store.listRecoveryCodes(userId),
    ]);
    return totp.some((item) => item.verifiedAt) || recovery.some((item) => !item.usedAt);
  }

  async function availableMfaMethods(
    userId: string,
  ): Promise<Array<"email-otp" | "sms-otp" | "totp" | "recovery-code">> {
    const [identities, totp, recovery] = await Promise.all([
      store.listIdentities(userId),
      store.listTotp(userId),
      store.listRecoveryCodes(userId),
    ]);
    const methods: Array<"email-otp" | "sms-otp" | "totp" | "recovery-code"> = [];
    if (identities.some((item) => item.type === "email" && item.verifiedAt)) {
      methods.push("email-otp");
    }
    if (identities.some((item) => item.type === "phone" && item.verifiedAt)) {
      methods.push("sms-otp");
    }
    if (totp.some((item) => item.verifiedAt)) methods.push("totp");
    if (recovery.some((item) => !item.usedAt)) methods.push("recovery-code");
    return methods;
  }

  const engine: AuthEngine = {
    store,
    onSignedIn: options.onSignedIn,
    onSignedOut: options.onSignedOut,
    onSuccessfulSignUp: options.onSuccessfulSignUp ?? options.onSuccessfullSignUp,

    async register(input) {
      try {
        await assertPasswordPolicy(input.password);
        if (!input.email && !input.phone && !input.username)
          throw new Error("Email, phone, or username is required");
        for (const [type, value] of [
          ["email", input.email],
          ["phone", input.phone],
          ["username", input.username],
        ] as const) {
          if (value) {
            const normalized = validatedIdentity(type, value);
            if (await store.findIdentity(type, normalized)) {
              throw new Error(`${type} is already in use`);
            }
          }
        }
        const timestamp = now();
        const user: AuthUser = {
          id: id("usr"),
          username: input.username?.trim(),
          displayName: input.displayName?.trim(),
          status: "pending",
          roles: ["user"],
          emailVerified: false,
          phoneVerified: false,
          mfaEnabled: false,
          locale: input.locale,
          timezone: input.timezone,
          createdAt: timestamp,
          updatedAt: timestamp,
          metadata: input.metadata,
        };
        await store.createUser(user);
        if (input.email) await createIdentity(user.id, "email", input.email, true);
        if (input.phone) await createIdentity(user.id, "phone", input.phone, !input.email);
        if (input.username)
          await createIdentity(user.id, "username", input.username, !input.email && !input.phone);
        await store.setPassword({
          userId: user.id,
          passwordHash: await hashPassword(input.password),
          passwordVersion: 1,
          changedAt: timestamp,
          mustChange: false,
        });
        const identities = await store.listIdentities(user.id);
        const email = identities.find((item) => item.type === "email");
        const phone = identities.find((item) => item.type === "phone");
        if (email) await sendToken(user, "verify-email", email.value);
        if (phone) await sendToken(user, "verify-phone", phone.value);
        await audit({ userId: user.id, type: "account.registered", severity: "info" });
        return {
          ok: true,
          user: publicUser(user),
          requires: {
            emailVerification: Boolean(email),
            phoneVerification: Boolean(phone),
          },
        };
      } catch (error) {
        return {
          ok: false,
          code: "registration-failed",
          message: error instanceof Error ? error.message : "Registration failed",
        };
      }
    },

    async login(input) {
      const identifier = safeIdentifier(input.identifier);
      const user = await findUserByIdentifier(identifier);
      if (user) await restoreExpiredLoginLock(user);
      const recent = await store.listRecentLoginAttempts(identifier, now() - lockDurationMs);
      const failedAttempts = recent.filter((attempt) => !attempt.success).length;
      let breachedPassword = false;
      if (options.breachProvider)
        breachedPassword = await options.breachProvider.isBreached(input.password);
      const risk = evaluateAuthRisk(
        {
          ...input.signals,
          failedAttempts,
          breachedPassword,
          accountLocked: user?.status === "locked",
        },
        {
          captchaThreshold: options.captchaThreshold ?? 35,
          mfaThreshold: options.mfaThreshold ?? 60,
          blockThreshold: options.blockThreshold ?? 90,
        },
      );
      if (!input.captchaVerified && risk.requireCaptcha && !risk.block) {
        await store.createLoginAttempt({
          id: id("log"),
          identifier,
          userId: user?.id,
          success: false,
          reason: "captcha-required",
          ip: input.ip,
          userAgent: input.userAgent,
          createdAt: now(),
          riskScore: risk.score,
          riskLevel: risk.level,
        });
        return {
          ok: false,
          code: "captcha-required",
          message: "Complete the security check shown on the sign-in form, then try again.",
          risk,
          requires: { captcha: true },
        };
      }
      if (!user || risk.block) {
        await consumeUnknownPasswordAttempt(input.password);
        await store.createLoginAttempt({
          id: id("log"),
          identifier,
          userId: user?.id,
          success: false,
          reason: risk.block ? "risk-blocked" : "unknown-user",
          ip: input.ip,
          userAgent: input.userAgent,
          createdAt: now(),
          riskScore: risk.score,
          riskLevel: risk.level,
        });
        return {
          ok: false,
          code: risk.block ? "risk-blocked" : "invalid-credentials",
          message: risk.block
            ? "Sign-in was blocked because of unusual activity. Wait a few minutes and try again."
            : "The email, phone, username, or password you entered is incorrect.",
          risk,
          requires: { captcha: risk.requireCaptcha },
        };
      }
      const credential = await store.getPassword(user.id);
      const valid = credential
        ? await verifyPassword(input.password, credential.passwordHash)
        : (await consumeUnknownPasswordAttempt(input.password), false);
      await store.createLoginAttempt({
        id: id("log"),
        identifier,
        userId: user.id,
        success: valid,
        reason: valid ? undefined : "invalid-password",
        ip: input.ip,
        userAgent: input.userAgent,
        createdAt: now(),
        riskScore: risk.score,
        riskLevel: risk.level,
      });
      if (!valid) {
        await audit({
          userId: user.id,
          type: "login.failed",
          severity: "warning",
          ip: input.ip,
          userAgent: input.userAgent,
          data: { risk },
        });
        if (failedAttempts + 1 >= maxFailedLogins) {
          const previousStatus = user.status;
          user.status = "locked";
          user.updatedAt = now();
          user.metadata = {
            ...user.metadata,
            lockedUntil: now() + lockDurationMs,
            lockReason: "failed-login",
            lockedPreviousStatus: previousStatus,
          };
          await store.updateUser(user);
        }
        return {
          ok: false,
          code: "invalid-credentials",
          message: "The email, phone, username, or password you entered is incorrect.",
          risk,
          requires: { captcha: risk.requireCaptcha },
        };
      }
      // Check account state only after proving the password so public login
      // responses do not reveal whether a known identifier is disabled or locked.
      const accountUnavailable = accountStatusUnavailable(user);
      if (accountUnavailable) return { ...accountUnavailable, risk };
      const verification = verificationUnavailable(user);
      if (verification) return { ...verification, risk };
      const mfaEnabled = await hasMfa(user.id);
      const trustedDevice = input.fingerprint
        ? await store.findTrustedDeviceByFingerprint(user.id, await fingerprint(input.fingerprint))
        : undefined;
      const trusted = Boolean(
        trustedDevice && !trustedDevice.revokedAt && trustedDevice.expiresAt > now(),
      );
      user.mfaEnabled = mfaEnabled;
      if (
        (mfaEnabled && !((options.skipMfaForTrustedDevices ?? true) && trusted)) ||
        risk.requireMfa
      ) {
        await store.updateUser(user);
        const methods = await availableMfaMethods(user.id);
        if (!methods.length) {
          return {
            ok: false,
            code: "mfa-unavailable",
            message: "Additional verification is required but no verification method is available",
            risk,
          };
        }
        const mfaToken = await issueToken(user.id, "login-mfa", {
          ttlMs: 5 * 60_000,
          metadata: {
            ip: input.ip,
            userAgent: input.userAgent,
            deviceId: input.deviceId,
            deviceName: input.deviceName,
            fingerprint: input.fingerprint,
            rememberDevice: input.rememberDevice,
          },
        });
        return {
          ok: false,
          code: "mfa-required",
          message: "Complete two-step verification to finish signing in.",
          user: publicUser(user),
          risk,
          mfaToken,
          requires: { captcha: risk.requireCaptcha, mfa: methods },
        };
      }
      const rememberedDevice =
        input.rememberDevice && input.fingerprint
          ? await engine.trustDevice(user.id, {
              fingerprint: input.fingerprint,
              name: input.deviceName,
            })
          : undefined;
      const session = await createSession(user.id, {
        ip: input.ip,
        userAgent: input.userAgent,
        deviceId: rememberedDevice?.id ?? input.deviceId,
        trusted: Boolean(rememberedDevice),
        fingerprint: input.fingerprint,
        deviceName: input.deviceName,
      });
      user.status = "active";
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "login.succeeded",
        severity: "info",
        ip: input.ip,
        userAgent: input.userAgent,
        data: { risk, trustedDevice: session.trusted },
      });
      await sendLoginAlert(user, session);
      return { ok: true, user: publicUser(user), session, risk };
    },

    async logout(sessionId, reason = "user-logout") {
      const session = await store.findSession(sessionId);
      if (!session) return;
      session.revokedAt = now();
      session.revokeReason = reason;
      await store.updateSession(session);
      await audit({
        userId: session.userId,
        sessionId,
        type: "session.revoked",
        severity: "info",
        data: { reason },
      });
    },

    findUserByIdentifier,
    getUser: (userId) => store.findUserById(userId),
    async getPublicUser(userId) {
      const user = await store.findUserById(userId);
      return user ? publicUser(user) : undefined;
    },
    createSession,
    validateSession,
    async listSessions(userId) {
      const timestamp = now();
      const sessions = await store.listSessions(userId);
      const active: AuthSession[] = [];
      for (const session of sessions) {
        if (session.revokedAt) continue;
        if (session.expiresAt <= timestamp || session.absoluteExpiresAt <= timestamp) {
          await store.deleteSession(session.id);
          continue;
        }
        active.push(session);
      }
      return active.sort((left, right) => right.lastSeenAt - left.lastSeenAt);
    },

    async revokeSession(userId, sessionId, reason = "user-revoked") {
      const session = await store.findSession(sessionId);
      if (!session || session.userId !== userId) return false;
      session.revokedAt = now();
      session.revokeReason = reason;
      await store.updateSession(session);
      await audit({
        userId,
        sessionId,
        type: "session.revoked",
        severity: "warning",
        data: { reason },
      });
      return true;
    },

    async revokeAllSessions(userId, exceptSessionId, reason = "all-sessions-revoked") {
      const sessions = await store.listSessions(userId);
      let count = 0;
      for (const session of sessions) {
        if (session.id === exceptSessionId || session.revokedAt) continue;
        session.revokedAt = now();
        session.revokeReason = reason;
        await store.updateSession(session);
        count += 1;
      }
      if (count)
        await audit({
          userId,
          type: "session.revoked-all",
          severity: "warning",
          data: { count, exceptSessionId, reason },
        });
      return count;
    },

    async trustDevice(userId, input) {
      if (!(await store.findUserById(userId))) throw new Error("User not found");
      const timestamp = now();
      const hash = await fingerprint(input.fingerprint);
      const existing = await store.findTrustedDeviceByFingerprint(userId, hash);
      if (existing) {
        existing.name = input.name ?? existing.name;
        existing.lastSeenAt = timestamp;
        existing.expiresAt = timestamp + trustedTtlMs;
        existing.revokedAt = undefined;
        await store.updateTrustedDevice(existing);
        return existing;
      }
      const device: TrustedDevice = {
        id: id("dev"),
        userId,
        name: input.name ?? "Trusted device",
        fingerprintHash: hash,
        createdAt: timestamp,
        lastSeenAt: timestamp,
        expiresAt: timestamp + trustedTtlMs,
      };
      await store.createTrustedDevice(device);
      await audit({
        userId,
        type: "device.trusted",
        severity: "info",
        data: { deviceId: device.id, name: device.name },
      });
      return device;
    },
    listTrustedDevices: (userId) => store.listTrustedDevices(userId),
    async revokeTrustedDevice(userId, deviceId) {
      const device = (await store.listTrustedDevices(userId)).find((item) => item.id === deviceId);
      if (!device) return false;
      device.revokedAt = now();
      await store.updateTrustedDevice(device);
      await audit({ userId, type: "device.revoked", severity: "warning", data: { deviceId } });
      return true;
    },

    issueToken,
    consumeToken,
    async verifyEmail(token) {
      const record = await inspectToken(token, "verify-email");
      if (!record)
        return {
          ok: false,
          code: "invalid-token",
          message: "Verification link is invalid or expired",
        };
      const user = await store.findUserById(record.userId);
      if (!user)
        return {
          ok: false,
          code: "invalid-token",
          message: "Verification link is invalid or expired",
        };
      const unavailable = recoveryUnavailable(user);
      if (unavailable) return unavailable;
      if (!(await markVerified(user, "email", record.target))) {
        return { ok: false, code: "identity-missing", message: "Email identity is unavailable" };
      }
      await consumeInspectedToken(record);
      await audit({ userId: user.id, type: "identity.email-verified", severity: "info" });
      return { ok: true, user: publicUser(user) };
    },
    async verifyPhone(token) {
      const record = await inspectToken(token, "verify-phone");
      if (!record)
        return {
          ok: false,
          code: "invalid-token",
          message: "Verification code is invalid or expired",
        };
      const user = await store.findUserById(record.userId);
      if (!user)
        return {
          ok: false,
          code: "invalid-token",
          message: "Verification code is invalid or expired",
        };
      const unavailable = recoveryUnavailable(user);
      if (unavailable) return unavailable;
      if (!(await markVerified(user, "phone", record.target))) {
        return { ok: false, code: "identity-missing", message: "Phone identity is unavailable" };
      }
      await consumeInspectedToken(record);
      await audit({ userId: user.id, type: "identity.phone-verified", severity: "info" });
      return { ok: true, user: publicUser(user) };
    },

    async requestVerification(userId, type, baseUrl) {
      const user = await store.findUserById(userId);
      if (!user || user.status === "disabled" || user.status === "deleted") return;
      const identities = await store.listIdentities(userId);
      const identity =
        identities.find((item) => item.type === type && item.primary) ??
        identities.find((item) => item.type === type);
      if (!identity || identity.verifiedAt) return;
      await sendToken(
        user,
        type === "email" ? "verify-email" : "verify-phone",
        identity.value,
        baseUrl,
      );
      await audit({ userId, type: `identity.${type}-verification-requested`, severity: "info" });
    },

    async requestPasswordReset(identifier, baseUrl) {
      const user = await findUserByIdentifier(identifier);
      if (!user || user.status === "disabled" || user.status === "deleted") return;
      const identities = await store.listIdentities(user.id);
      const target =
        identities.find((item) => item.type === "email" && item.primary)?.value ??
        identities.find((item) => item.type === "email")?.value;
      if (target) await sendToken(user, "password-reset", target, baseUrl);
      await audit({ userId: user.id, type: "password.reset-requested", severity: "info" });
    },

    async resetPassword(token, password) {
      try {
        await assertPasswordPolicy(password);
      } catch (error) {
        return {
          ok: false,
          code: "password-policy",
          message: error instanceof Error ? error.message : "Password does not meet policy",
        };
      }
      const record = await inspectToken(token, "password-reset");
      if (!record)
        return { ok: false, code: "invalid-token", message: "Reset link is invalid or expired" };
      const user = await store.findUserById(record.userId);
      if (!user)
        return { ok: false, code: "invalid-token", message: "Reset link is invalid or expired" };
      const unavailable = recoveryUnavailable(user);
      if (unavailable) return unavailable;
      await consumeInspectedToken(record);
      const current = await store.getPassword(user.id);
      await store.setPassword({
        userId: user.id,
        passwordHash: await hashPassword(password),
        passwordVersion: (current?.passwordVersion ?? 0) + 1,
        changedAt: now(),
        mustChange: false,
      });
      await clearFailedLoginLock(user);
      await engine.revokeAllSessions(user.id, undefined, "password-reset");
      await audit({ userId: user.id, type: "password.reset", severity: "warning" });
      return { ok: true, user: publicUser(user) };
    },

    async createInvitation(input) {
      const normalized = validatedIdentity("email", input.email);
      const existingIdentity = await store.findIdentity("email", normalized);
      let user = existingIdentity ? await store.findUserById(existingIdentity.userId) : undefined;
      if (!user) {
        const timestamp = now();
        user = {
          id: id("usr"),
          displayName: input.displayName?.trim(),
          status: "pending",
          roles: input.roles?.length ? [...new Set(input.roles)] : ["user"],
          emailVerified: false,
          phoneVerified: false,
          mfaEnabled: false,
          createdAt: timestamp,
          updatedAt: timestamp,
          metadata: input.metadata,
        };
        await store.createUser(user);
        await createIdentity(user.id, "email", input.email, true);
      }
      const token = await issueToken(user.id, "invite", {
        target: input.email,
        ttlMs: input.ttlMs,
        metadata: { invitedBy: input.invitedBy, roles: input.roles, ...input.metadata },
      });
      const url = actionUrl(user, "invite", token, input.email, input.baseUrl);
      await deliver({
        channel: "email",
        template: "invitation",
        destination: input.email,
        token,
        url,
        user: publicUser(user),
        expiresAt: now() + tokenTtl("invite", input.ttlMs),
        data: { invitedBy: input.invitedBy },
      });
      await audit({
        userId: user.id,
        actorUserId: input.invitedBy,
        type: "invitation.created",
        severity: "info",
      });
      return { token, user: publicUser(user) };
    },

    async acceptInvitation(raw, input) {
      const token = await inspectToken(raw, "invite");
      if (!token)
        return {
          ok: false,
          code: "invalid-invitation",
          message: "Invitation is invalid or expired",
        };
      const user = await store.findUserById(token.userId);
      if (!user || user.status === "deleted" || user.status === "disabled") {
        return { ok: false, code: "account-unavailable" };
      }
      const credential = await store.getPassword(user.id);
      if (!credential) {
        if (!input.password)
          return {
            ok: false,
            code: "password-required",
            message: "Create a password to accept this invitation",
          };
        try {
          await assertPasswordPolicy(input.password);
        } catch (error) {
          return {
            ok: false,
            code: "password-policy",
            message: error instanceof Error ? error.message : "Password does not meet policy",
          };
        }
        await store.setPassword({
          userId: user.id,
          passwordHash: await hashPassword(input.password),
          passwordVersion: 1,
          changedAt: now(),
          mustChange: false,
        });
      }
      if (input.displayName?.trim()) user.displayName = input.displayName.trim();
      const roles = Array.isArray(token.metadata?.roles)
        ? token.metadata.roles.filter((role): role is string => typeof role === "string")
        : [];
      if (roles.length) user.roles = [...new Set([...user.roles, ...roles])];
      if (!(await markVerified(user, "email", token.target))) {
        return { ok: false, code: "invitation-identity-missing" };
      }
      user.status = "active";
      user.updatedAt = now();
      await store.updateUser(user);
      await consumeInspectedToken(token);
      await audit({
        userId: user.id,
        actorUserId:
          typeof token.metadata?.invitedBy === "string" ? token.metadata.invitedBy : undefined,
        type: "invitation.accepted",
        severity: "info",
      });
      return { ok: true, user: publicUser(user) };
    },

    async requestMagicLink(identifier, baseUrl) {
      const user = await findUserByIdentifier(identifier);
      if (!user) return;
      await restoreExpiredLoginLock(user);
      if (accountStatusUnavailable(user)?.code?.startsWith("account-")) return;
      const identities = await store.listIdentities(user.id);
      const target =
        identities.find((item) => item.type === "email" && item.primary)?.value ??
        identities.find((item) => item.type === "email")?.value;
      if (target) await sendToken(user, "magic-link", target, baseUrl);
    },

    async consumeMagicLink(token, sessionInput = {}) {
      const consumed = await consumeTokenRecord(token, "magic-link");
      if (!consumed)
        return { ok: false, code: "invalid-token", message: "Magic link is invalid or expired" };
      const { user, token: record } = consumed;
      await restoreExpiredLoginLock(user);
      const blocked = accountStatusUnavailable(user);
      if (blocked?.code?.startsWith("account-")) return blocked;
      if (!(await markVerified(user, "email", record.target))) {
        return { ok: false, code: "identity-missing", message: "Email identity is unavailable" };
      }
      const verification = verificationUnavailable(user);
      if (verification) return verification;
      const mfa = await mfaRequirement(user, {
        ip: sessionInput.ip,
        userAgent: sessionInput.userAgent,
        deviceId: sessionInput.deviceId,
      });
      if (mfa) return mfa;
      const session = await createSession(user.id, sessionInput);
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "login.magic-link",
        severity: "info",
      });
      await sendLoginAlert(user, session);
      return { ok: true, user: publicUser(user), session };
    },

    issueOtp,
    async verifyOtp(challengeId, code, expectedPurpose = "verification") {
      const challenge = await store.findOtp(challengeId);
      if (
        !challenge ||
        challenge.purpose !== expectedPurpose ||
        challenge.usedAt ||
        challenge.expiresAt <= now()
      )
        return { ok: false, code: "invalid-otp", message: "Code is invalid or expired" };
      challenge.attempts += 1;
      if (challenge.attempts > challenge.maxAttempts) {
        await store.updateOtp(challenge);
        return { ok: false, code: "attempts-exhausted", message: "Too many attempts" };
      }
      const normalizedCode = code.trim();
      const validShape = /^\d{6}$/.test(normalizedCode);
      const actual = await hashSecret(validShape ? normalizedCode : "000000", options.secret);
      if (!validShape || !(await constantTimeEqual(actual, challenge.codeHash))) {
        await store.updateOtp(challenge);
        return { ok: false, code: "invalid-otp", message: "Code is incorrect" };
      }
      challenge.usedAt = now();
      await store.updateOtp(challenge);
      const user = await store.findUserById(challenge.userId);
      if (!user) return { ok: false, code: "user-missing" };
      const identityVerified =
        challenge.method === "email-otp"
          ? await markVerified(user, "email", challenge.destination)
          : await markVerified(user, "phone", challenge.destination);
      if (!identityVerified) {
        return { ok: false, code: "identity-missing", message: "OTP identity is unavailable" };
      }
      await audit({
        userId: user.id,
        type:
          expectedPurpose === "mfa"
            ? "mfa.otp-verified"
            : expectedPurpose === "login"
              ? "login.otp-verified"
              : "identity.otp-verified",
        severity: "info",
        data: { method: challenge.method },
      });
      return { ok: true, user: publicUser(user) };
    },

    async requestOtpLogin(identifier, method) {
      const user = await findUserByIdentifier(safeIdentifier(identifier));
      if (!user || !["active", "pending"].includes(user.status)) {
        // Keep the public response shape and timing independent of account
        // existence. The fake challenge is deliberately not persisted, so any
        // completion attempt fails with the same generic invalid-code result.
        return {
          id: id("otp"),
          expiresAt: now() + otpTtlMs,
        };
      }
      try {
        return await issueOtp(user.id, method, undefined, "login");
      } catch {
        return {
          id: id("otp"),
          expiresAt: now() + otpTtlMs,
        };
      }
    },

    async completeOtpLogin(challengeId, code, sessionInput = {}) {
      const challenge = await store.findOtp(challengeId);
      if (!challenge)
        return { ok: false, code: "invalid-otp", message: "Code is invalid or expired" };
      if (challenge.purpose !== "login") {
        return { ok: false, code: "invalid-otp", message: "Code is invalid or expired" };
      }
      const verified = await engine.verifyOtp(challengeId, code, "login");
      if (!verified.ok || !verified.user) return verified;
      const user = await store.findUserById(challenge.userId);
      if (!user)
        return { ok: false, code: "account-unavailable", message: "This account cannot sign in" };
      await restoreExpiredLoginLock(user);
      const unavailable = accountStatusUnavailable(user);
      if (unavailable) return unavailable;
      const verification = verificationUnavailable(user);
      if (verification) return verification;
      const mfa = await mfaRequirement(user, {
        ip: sessionInput.ip,
        userAgent: sessionInput.userAgent,
        deviceId: sessionInput.deviceId,
      });
      if (mfa) return mfa;
      const session = await createSession(user.id, sessionInput);
      user.status = "active";
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "login.otp",
        severity: "info",
        data: { method: challenge.method },
      });
      await sendLoginAlert(user, session);
      return { ok: true, user: publicUser(user), session };
    },

    async beginMfaOtp(mfaToken, method) {
      const token = await inspectToken(mfaToken, "login-mfa");
      if (!token) return undefined;
      const user = await store.findUserById(token.userId);
      if (!user) return undefined;
      await restoreExpiredLoginLock(user);
      if (accountStatusUnavailable(user) || verificationUnavailable(user)) return undefined;
      try {
        return await issueOtp(token.userId, method, undefined, "mfa");
      } catch {
        return undefined;
      }
    },

    async completeMfa(input) {
      const transaction = await inspectToken(input.mfaToken, "login-mfa");
      if (!transaction)
        return {
          ok: false,
          code: "mfa-transaction-expired",
          message: "Sign-in verification expired",
        };
      const transactionUser = await store.findUserById(transaction.userId);
      if (!transactionUser) return { ok: false, code: "user-missing" };
      await restoreExpiredLoginLock(transactionUser);
      const unavailable = accountStatusUnavailable(transactionUser);
      if (unavailable) return unavailable;
      const verification = verificationUnavailable(transactionUser);
      if (verification) return verification;
      let verified = false;
      if (input.method === "totp")
        verified = await engine.verifyTotp(transaction.userId, input.code);
      else if (input.method === "recovery-code")
        verified = await engine.consumeRecoveryCode(transaction.userId, input.code);
      else if (input.challengeId) {
        const otp = await store.findOtp(input.challengeId);
        if (
          otp?.userId === transaction.userId &&
          otp.method === input.method &&
          otp.purpose === "mfa"
        ) {
          verified = (await engine.verifyOtp(input.challengeId, input.code, "mfa")).ok;
        }
      }
      if (!verified) {
        transaction.attempts += 1;
        if (transaction.attempts >= transaction.maxAttempts) transaction.usedAt = now();
        await store.updateToken(transaction);
        await audit({
          userId: transaction.userId,
          type: "mfa.failed",
          severity: "warning",
          data: { method: input.method },
        });
        return { ok: false, code: "mfa-invalid", message: "Verification failed" };
      }
      await consumeInspectedToken(transaction);
      const user = transactionUser;
      const metadata = transaction.metadata ?? {};
      const rememberedDevice =
        metadata.rememberDevice === true && typeof metadata.fingerprint === "string"
          ? await engine.trustDevice(user.id, {
              fingerprint: metadata.fingerprint,
              name: typeof metadata.deviceName === "string" ? metadata.deviceName : undefined,
            })
          : undefined;
      const session = await createSession(user.id, {
        ...input.session,
        ip: input.session?.ip ?? (typeof metadata.ip === "string" ? metadata.ip : undefined),
        userAgent:
          input.session?.userAgent ??
          (typeof metadata.userAgent === "string" ? metadata.userAgent : undefined),
        deviceId:
          rememberedDevice?.id ??
          input.session?.deviceId ??
          (typeof metadata.deviceId === "string" ? metadata.deviceId : undefined),
        trusted: Boolean(rememberedDevice) || input.session?.trusted === true,
        fingerprint: typeof metadata.fingerprint === "string" ? metadata.fingerprint : undefined,
      });
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "mfa.succeeded",
        severity: "info",
        data: { method: input.method },
      });
      return { ok: true, user: publicUser(user), session };
    },

    async beginTotp(userId, label = "Authenticator") {
      const user = await store.findUserById(userId);
      if (!user) throw new Error("User not found");
      for (const existing of await store.listTotp(userId)) {
        if (!existing.verifiedAt) await store.deleteTotp(existing.id);
      }
      const identities = await store.listIdentities(userId);
      const accountName =
        identities.find((item) => item.type === "email")?.value ?? user.username ?? user.id;
      const secret = generateTotpSecret(random);
      const credentialId = id("totp");
      await store.createTotp({
        id: credentialId,
        userId,
        label,
        secret: await protect(secret, "totp"),
        createdAt: now(),
      });
      return { credentialId, secret, uri: totpUri({ issuer, accountName, secret }) };
    },

    async confirmTotp(userId, credentialId, token) {
      const credential = (await store.listTotp(userId)).find((item) => item.id === credentialId);
      if (!credential || credential.verifiedAt) return false;
      const result = await verifyTotp(await reveal(credential.secret, "totp"), token, {
        timestamp: now(),
      });
      if (!result.valid) return false;
      credential.verifiedAt = now();
      credential.lastCounter = result.counter;
      await store.updateTotp(credential);
      const user = await store.findUserById(userId);
      if (user) {
        user.mfaEnabled = true;
        user.updatedAt = now();
        await store.updateUser(user);
      }
      await audit({ userId, type: "mfa.totp-enabled", severity: "info", data: { credentialId } });
      return true;
    },

    async verifyTotp(userId, token) {
      for (const credential of await store.listTotp(userId)) {
        if (!credential.verifiedAt) continue;
        const result = await verifyTotp(await reveal(credential.secret, "totp"), token, {
          timestamp: now(),
          lastCounter: credential.lastCounter,
        });
        if (!result.valid) continue;
        credential.lastCounter = result.counter;
        await store.updateTotp(credential);
        await audit({
          userId,
          type: "mfa.totp-verified",
          severity: "info",
          data: { credentialId: credential.id },
        });
        return true;
      }
      return false;
    },

    async disableTotp(userId, credentialId) {
      const credential = (await store.listTotp(userId)).find((item) => item.id === credentialId);
      if (!credential) return false;
      await store.deleteTotp(credentialId);
      const user = await store.findUserById(userId);
      if (user) {
        user.mfaEnabled = await hasMfa(userId);
        user.updatedAt = now();
        await store.updateUser(user);
      }
      await audit({
        userId,
        type: "mfa.totp-disabled",
        severity: "warning",
        data: { credentialId },
      });
      return true;
    },

    async generateRecoveryCodes(userId, count = 10) {
      if (!Number.isInteger(count) || count < 1 || count > 50)
        throw new RangeError("Recovery code count must be between 1 and 50");
      const user = await store.findUserById(userId);
      if (!user) throw new Error("User not found");
      const timestamp = now();
      const plain: string[] = [];
      const records = [];
      for (let index = 0; index < count; index += 1) {
        const raw = `${randomReadableCode(random, 5)}-${randomReadableCode(random, 5)}`;
        plain.push(raw);
        records.push({
          id: id("rcv"),
          userId,
          codeHash: await hashSecret(raw, options.secret),
          createdAt: timestamp,
        });
      }
      // Regeneration invalidates every previously issued code. Keeping old
      // unused codes valid would make the security action misleading.
      await store.deleteRecoveryCodes(userId);
      await store.createRecoveryCodes(records);
      user.mfaEnabled = true;
      user.updatedAt = timestamp;
      await store.updateUser(user);
      await audit({
        userId,
        type: "mfa.recovery-codes-generated",
        severity: "warning",
        data: { count },
      });
      return plain;
    },

    async consumeRecoveryCode(userId, code) {
      const hash = await hashSecret(code.trim().toUpperCase(), options.secret);
      for (const record of await store.listRecoveryCodes(userId)) {
        if (record.usedAt || !(await constantTimeEqual(record.codeHash, hash))) continue;
        record.usedAt = now();
        await store.updateRecoveryCode(record);
        const user = await store.findUserById(userId);
        if (user) {
          user.mfaEnabled = await hasMfa(userId);
          user.updatedAt = now();
          await store.updateUser(user);
        }
        await audit({
          userId,
          type: "mfa.recovery-code-used",
          severity: "warning",
          data: { codeId: record.id },
        });
        return true;
      }
      return false;
    },

    async listRecoveryCodeStatus(userId) {
      const records = await store.listRecoveryCodes(userId);
      return { total: records.length, remaining: records.filter((item) => !item.usedAt).length };
    },

    async linkOAuth(userId, provider, profile, tokens) {
      if (!(await store.findUserById(userId))) throw new Error("User not found");
      const providerName = normalizedOAuthProvider(provider);
      const providerAccountId = normalizedOAuthAccountId(profile.id);
      const existing = await store.findOAuthAccount(providerName, providerAccountId);
      if (existing && existing.userId !== userId)
        throw new Error("OAuth account is already linked");
      const timestamp = now();
      const account: OAuthAccount = existing ?? {
        id: id("oauth"),
        userId,
        provider: providerName,
        providerAccountId,
        createdAt: timestamp,
        updatedAt: timestamp,
      };
      if (profile.email !== undefined) account.email = profile.email;
      if (tokens && "access_token" in tokens) {
        account.accessToken = tokens.access_token
          ? await protect(tokens.access_token, "oauth-access")
          : undefined;
      }
      if (tokens && "refresh_token" in tokens) {
        account.refreshToken = tokens.refresh_token
          ? await protect(tokens.refresh_token, "oauth-refresh")
          : undefined;
      }
      if (tokens && "expires_in" in tokens) {
        const expiresIn = Number(tokens.expires_in);
        if (Number.isFinite(expiresIn) && expiresIn > 0) {
          account.tokenExpiresAt = timestamp + Math.trunc(expiresIn * 1000);
        } else if (tokens.expires_in === 0 || tokens.expires_in == null) {
          account.tokenExpiresAt = undefined;
        }
      }
      if (tokens && "scope" in tokens) account.scope = tokens.scope;
      account.updatedAt = timestamp;
      if (existing) await store.updateOAuthAccount(account);
      else await store.createOAuthAccount(account);
      await audit({
        userId,
        type: "oauth.linked",
        severity: "info",
        data: { provider: providerName, accountId: account.id },
      });
      return account;
    },

    async loginWithOAuth(provider, profile, tokens) {
      const providerName = normalizedOAuthProvider(provider);
      const providerAccountId = normalizedOAuthAccountId(profile.id);
      let account = await store.findOAuthAccount(providerName, providerAccountId);
      let user = account ? await store.findUserById(account.userId) : undefined;
      const normalizedProfile = { ...profile, id: providerAccountId };
      const verifiedEmail = await oauthEmailVerified(providerName, normalizedProfile);
      if (!user && profile.email) {
        const identity = await store.findIdentity(
          "email",
          normalizeIdentity("email", profile.email),
        );
        if (identity) {
          if (!verifiedEmail || options.linkVerifiedOAuthEmails === false) {
            return {
              ok: false,
              code: "oauth-link-required",
              message: "Sign in to the existing account before linking this provider",
            };
          }
          user = await store.findUserById(identity.userId);
          if (user && verifiedEmail) await markVerified(user, "email", profile.email);
        }
      }
      if (!user) {
        const timestamp = now();
        user = {
          id: id("usr"),
          displayName: profile.name,
          avatarUrl: profile.avatar,
          status: verifiedEmail || !profile.email ? "active" : "pending",
          roles: ["user"],
          emailVerified: verifiedEmail,
          phoneVerified: false,
          mfaEnabled: false,
          createdAt: timestamp,
          updatedAt: timestamp,
        };
        await store.createUser(user);
        if (profile.email) {
          const identity = await createIdentity(user.id, "email", profile.email, true);
          if (verifiedEmail) {
            identity.verifiedAt = timestamp;
            await store.updateIdentity(identity);
          }
        }
      }
      await restoreExpiredLoginLock(user);
      const unavailable = accountStatusUnavailable(user);
      if (unavailable) return unavailable;
      const verification = verificationUnavailable(user);
      if (verification) return verification;
      account = await engine.linkOAuth(user.id, providerName, normalizedProfile, tokens);
      if (await hasMfa(user.id)) {
        const methods = await availableMfaMethods(user.id);
        const mfaToken = await issueToken(user.id, "login-mfa", {
          ttlMs: 5 * 60_000,
          metadata: { oauthProvider: providerName },
        });
        return {
          ok: false,
          code: "mfa-required",
          user: publicUser(user),
          mfaToken,
          requires: { mfa: methods },
        };
      }
      const session = await createSession(user.id);
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "login.oauth",
        severity: "info",
        data: { provider: providerName, accountId: account.id },
      });
      await sendLoginAlert(user, session);
      return { ok: true, user: publicUser(user), session };
    },

    async unlinkOAuth(userId, accountId) {
      const account = (await store.listOAuthAccounts(userId)).find((item) => item.id === accountId);
      if (!account) return false;
      const [password, accounts, passkeys, identities] = await Promise.all([
        store.getPassword(userId),
        store.listOAuthAccounts(userId),
        store.listPasskeys(userId),
        store.listIdentities(userId),
      ]);
      const canStillSignIn = Boolean(
        password ||
        accounts.some((item) => item.id !== accountId) ||
        passkeys.length ||
        (Boolean(options.delivery) &&
          identities.some((item) => item.type === "email" || item.type === "phone")),
      );
      if (!canStillSignIn) return false;
      await store.deleteOAuthAccount(accountId);
      await audit({
        userId,
        type: "oauth.unlinked",
        severity: "warning",
        data: { provider: account.provider, accountId },
      });
      return true;
    },

    async beginPasskeyRegistration(userId, input) {
      const provider = assertPasskeyProvider(options.passkeys);
      const user = await store.findUserById(userId);
      if (!user) throw new Error("User not found");
      const identities = await store.listIdentities(userId);
      const credentials = await store.listPasskeys(userId);
      const registration = await provider.registrationOptions({
        user,
        identities,
        credentials,
        ...input,
      });
      if (!registration.challenge) {
        throw new Error("WRN-AUTH-PASSKEY-PROVIDER: registration options omitted challenge");
      }
      const timeout = passkeyChallengeTtl(registration.timeout);
      const key = id("pkc");
      await passkeyChallenges.set(key, {
        challenge: registration.challenge,
        kind: "registration",
        userId,
        rpId: input.rpId,
        origin: input.origin,
        expiresAt: now() + timeout,
      });
      return { key, options: { ...registration, timeout } };
    },

    async finishPasskeyRegistration(userId, input) {
      const provider = assertPasskeyProvider(options.passkeys);
      const saved = await passkeyChallenges.consume(input.key);
      if (
        !saved ||
        saved.kind !== "registration" ||
        saved.userId !== userId ||
        saved.expiresAt <= now()
      )
        return false;
      const user = await store.findUserById(userId);
      if (!user) return false;
      const result = await provider.verifyRegistration({
        user,
        response: input.response,
        expectedChallenge: saved.challenge,
        expectedOrigin: saved.origin,
        expectedRpId: saved.rpId,
      });
      if (!result.verified || !result.credential) return false;
      const providedCredential = result.credential;
      if (
        !providedCredential.credentialId ||
        !providedCredential.publicKey ||
        !Number.isSafeInteger(providedCredential.counter) ||
        providedCredential.counter < 0
      ) {
        return false;
      }
      if (await store.findPasskeyByCredentialId(providedCredential.credentialId)) return false;
      try {
        await store.createPasskey({
          ...providedCredential,
          id: id("pky"),
          userId,
          name: input.name ?? result.credential.name ?? "Passkey",
          createdAt: now(),
        });
      } catch {
        return false;
      }
      user.mfaEnabled = await hasMfa(userId);
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({ userId, type: "passkey.registered", severity: "info" });
      return true;
    },

    async beginPasskeyAuthentication(input) {
      const provider = assertPasskeyProvider(options.passkeys);
      const user = input.identifier ? await findUserByIdentifier(input.identifier) : undefined;
      const credentials = user ? await store.listPasskeys(user.id) : [];
      const authentication = await provider.authenticationOptions({
        user,
        credentials,
        rpId: input.rpId,
        origin: input.origin,
      });
      if (!authentication.challenge) {
        throw new Error("WRN-AUTH-PASSKEY-PROVIDER: authentication options omitted challenge");
      }
      const timeout = passkeyChallengeTtl(authentication.timeout);
      const key = id("pkc");
      await passkeyChallenges.set(key, {
        challenge: authentication.challenge,
        kind: "authentication",
        userId: user?.id,
        rpId: input.rpId,
        origin: input.origin,
        expiresAt: now() + timeout,
      });
      return { key, options: { ...authentication, timeout } };
    },

    async finishPasskeyAuthentication(input) {
      const provider = assertPasskeyProvider(options.passkeys);
      const saved = await passkeyChallenges.consume(input.key);
      if (!saved || saved.kind !== "authentication" || saved.expiresAt <= now())
        return { ok: false, code: "passkey-challenge-expired" };
      const credentialId =
        typeof input.response === "object" && input.response
          ? String((input.response as Record<string, unknown>).id ?? "")
          : "";
      let credential = credentialId
        ? await store.findPasskeyByCredentialId(credentialId)
        : undefined;
      const result = await provider.verifyAuthentication({
        response: input.response,
        credential,
        expectedChallenge: saved.challenge,
        expectedOrigin: saved.origin,
        expectedRpId: saved.rpId,
      });
      if (!credential && result.credentialId) {
        credential = await store.findPasskeyByCredentialId(result.credentialId);
      }
      const userId = result.userId ?? credential?.userId ?? saved.userId;
      if (!result.verified || !userId)
        return { ok: false, code: "passkey-verification-failed", message: result.error };
      if (saved.userId && userId !== saved.userId) {
        return { ok: false, code: "passkey-user-mismatch" };
      }
      if (credential && credential.userId !== userId) {
        return { ok: false, code: "passkey-user-mismatch" };
      }
      const user = await store.findUserById(userId);
      if (!user) return { ok: false, code: "user-missing" };
      await restoreExpiredLoginLock(user);
      const unavailable = accountStatusUnavailable(user);
      if (unavailable) return unavailable;
      const verification = verificationUnavailable(user);
      if (verification) return verification;
      if (credential) {
        if (result.newCounter !== undefined) {
          if (
            !Number.isSafeInteger(result.newCounter) ||
            result.newCounter < 0 ||
            (credential.counter > 0 && result.newCounter <= credential.counter)
          ) {
            return { ok: false, code: "passkey-counter-regression" };
          }
          credential.counter = result.newCounter;
        }
        credential.lastUsedAt = now();
        await store.updatePasskey(credential);
      }
      const session = await createSession(user.id, input.session);
      user.lastLoginAt = now();
      user.updatedAt = now();
      await store.updateUser(user);
      await audit({
        userId: user.id,
        sessionId: session.id,
        type: "login.passkey",
        severity: "info",
      });
      await sendLoginAlert(user, session);
      return { ok: true, user: publicUser(user), session };
    },

    async changePassword(userId, currentPassword, nextPassword) {
      const user = await store.findUserById(userId);
      if (!user || user.status === "disabled" || user.status === "deleted") {
        return {
          ok: false,
          code: "account-unavailable",
          message: "Password change is unavailable",
        };
      }
      const credential = await store.getPassword(userId);
      if (!credential || !(await verifyPassword(currentPassword, credential.passwordHash))) {
        return {
          ok: false,
          code: "invalid-current-password",
          message: "Current password is incorrect",
        };
      }
      try {
        await assertPasswordPolicy(nextPassword);
      } catch (error) {
        return {
          ok: false,
          code: "password-policy",
          message: error instanceof Error ? error.message : "Password does not meet policy",
        };
      }
      credential.passwordHash = await hashPassword(nextPassword);
      credential.passwordVersion += 1;
      credential.changedAt = now();
      credential.mustChange = false;
      await store.setPassword(credential);
      await engine.revokeAllSessions(userId, undefined, "password-changed");
      await audit({ userId, type: "password.changed", severity: "warning" });
      return { ok: true, user: publicUser(user) };
    },

    async setAccountStatus(userId, status, actorUserId) {
      const user = await store.findUserById(userId);
      if (!user) throw new Error("User not found");
      const previous = user.status;
      user.status = status;
      user.updatedAt = now();
      await store.updateUser(user);
      if (status !== "active")
        await engine.revokeAllSessions(userId, undefined, `account-${status}`);
      await audit({
        userId,
        actorUserId,
        type: "account.status-changed",
        severity: status === "active" ? "info" : "warning",
        data: { previous, status },
      });
    },

    async startImpersonation(actorUserId, targetUserId, input = {}) {
      const [actor, target] = await Promise.all([
        store.findUserById(actorUserId),
        store.findUserById(targetUserId),
      ]);
      if (!actor || !target || target.status !== "active") {
        return {
          ok: false,
          code: "impersonation-unavailable",
          message: "Impersonation is unavailable",
        };
      }
      const rawDecision = await options.authorizeImpersonation?.({
        actor,
        target,
        reason: input.reason,
      });
      const decision =
        typeof rawDecision === "boolean"
          ? { allowed: rawDecision }
          : (rawDecision ?? { allowed: false, reason: "No impersonation policy is configured" });
      if (!decision.allowed) {
        await audit({
          userId: target.id,
          actorUserId: actor.id,
          type: "impersonation.denied",
          severity: "warning",
          data: { reason: input.reason, policyReason: decision.reason },
        });
        return {
          ok: false,
          code: "impersonation-denied",
          message: decision.reason ?? "Impersonation was denied",
        };
      }
      const session = await createSession(target.id, {
        ip: input.ip,
        userAgent: input.userAgent,
        metadata: {
          impersonated: true,
          actorUserId: actor.id,
          actorSessionId: input.sessionId,
          reason: input.reason,
        },
      });
      await audit({
        userId: target.id,
        actorUserId: actor.id,
        sessionId: session.id,
        type: "impersonation.started",
        severity: "critical",
        data: { reason: input.reason, actorSessionId: input.sessionId },
      });
      return { ok: true, user: publicUser(target), session };
    },

    async stopImpersonation(sessionId) {
      const impersonated = await store.findSession(sessionId);
      const actorUserId =
        typeof impersonated?.metadata?.actorUserId === "string"
          ? impersonated.metadata.actorUserId
          : undefined;
      if (!impersonated || impersonated.metadata?.impersonated !== true || !actorUserId) {
        return {
          ok: false,
          code: "not-impersonating",
          message: "This session is not impersonating another account",
        };
      }
      impersonated.revokedAt = now();
      impersonated.revokeReason = "impersonation-ended";
      await store.updateSession(impersonated);
      const actor = await store.findUserById(actorUserId);
      if (!actor || actor.status !== "active") return { ok: false, code: "actor-unavailable" };
      const actorSessionId =
        typeof impersonated.metadata.actorSessionId === "string"
          ? impersonated.metadata.actorSessionId
          : undefined;
      let session = actorSessionId ? await validateSession(actorSessionId) : undefined;
      session ??= await createSession(actor.id);
      await audit({
        userId: impersonated.userId,
        actorUserId: actor.id,
        sessionId,
        type: "impersonation.ended",
        severity: "critical",
      });
      return { ok: true, user: publicUser(actor), session };
    },
  };

  return engine;
}
