import { NextResponse } from "next/server";
import { ensureDatabaseInitialized } from "@/lib/db/init";
import type { AuthErrorCode } from "./errors";

/**
 * Shared response helpers for the auth routes.
 *
 * Every failure is reported as a stable machine-readable `error` code from
 * `errors.ts`; the UI owns the wording so the same backend serves both languages
 * without the server knowing anything about copy.
 */

export function authError(
  error: AuthErrorCode,
  status: number,
  extra: Record<string, unknown> = {}
) {
  return NextResponse.json({ error, ...extra }, { status });
}

export function rateLimited(retryAfter: number) {
  return NextResponse.json(
    { error: "rate_limited" satisfies AuthErrorCode, retryAfter },
    { status: 429, headers: { "Retry-After": String(retryAfter) } }
  );
}

/**
 * Auth needs Postgres — unlike receipt scanning, which happily runs local-first
 * on IndexedDB. Fail with a clear code instead of a stack trace when the
 * database is down.
 *
 * Also runs the idempotent schema bootstrap so the very first auth request
 * repairs drift (missing tables/columns) instead of dying with a cryptic
 * `column does not exist`. `ensureDatabaseInitialized` is cached per process,
 * so this only runs once.
 */
export async function requireDatabase(): Promise<NextResponse | null> {
  if (await ensureDatabaseInitialized()) return null;
  return authError("database_unavailable", 503);
}

export async function readJson<T>(request: Request): Promise<T | null> {
  try {
    return (await request.json()) as T;
  } catch {
    return null;
  }
}
