import "server-only";

/**
 * Neon Auth (Better Auth) — server-side configuration.
 *
 * This file is Node-only. It is imported by:
 *   - `src/app/api/auth/[...nextauth]/route.ts` (the API handler)
 *   - Server actions that call signIn / signOut
 *   - `src/lib/admin-permissions.ts` (reads getSession() for the current user)
 *
 * The middleware imports a separate, edge-safe instance built from
 * `src/auth.config.ts`. Both instances share the same session cookie,
 * so the middleware can read sessions minted here.
 *
 * Auth providers: configured in the Neon Auth dashboard (oauth-provider).
 * Neon Auth manages its own users in the `neon_auth.user` table.
 * Our `admin_users` table links to Neon Auth users by email.
 */

import { createNeonAuth } from "@neondatabase/auth/next/server";
import { getNeonAuthConfig } from "@/auth.config";
import { cookies } from "next/headers";

const auth = createNeonAuth({
  baseUrl: getNeonAuthConfig().baseUrl,
  cookies: { secret: getNeonAuthConfig().cookieSecret },
});

const { getSession: _realGetSession, signIn, signOut, resetPassword, requestPasswordReset } = auth;
const { listUsers, createUser, setRole, setUserPassword, updateUser } = auth.admin;

export { signIn, signOut, resetPassword, requestPasswordReset };
export { listUsers, createUser, setRole, setUserPassword, updateUser };

/**
 * Fast-path wrapper around Neon Auth's `getSession()`.
 *
 * Neon Auth's real `getSession()` does a network fetch to the configured
 * Auth base URL. When the env var is unset (or set to the CI build-time
 * `placeholder.local`), every call hits a 30s DNS timeout before
 * returning `null`. Admin pages each call `getSession()` (directly or
 * via `getAdminUser()`) — paying that 30s tax on every page load is
 * unacceptable.
 *
 * Short-circuits when:
 *   1. `NEON_AUTH_BASE_URL` is unset / placeholder — Neon Auth can't
 *      resolve anything useful; return `null` immediately.
 *   2. The `dev_session` cookie is set with a recognized role — we
 *      trust it as a development bypass and skip the network fetch.
 *
 * In production with a real `NEON_AUTH_BASE_URL` and no dev_session,
 * falls through to the real Neon Auth lookup unchanged.
 */
function isAuthConfigured(): boolean {
  const url = process.env.NEON_AUTH_BASE_URL;
  if (!url || url === "placeholder" || url === "https://placeholder.local") return false;
  return true;
}

async function isDevSession(): Promise<boolean> {
  if (process.env.NODE_ENV === "production" && process.env.PERF_TEST_AUTH !== "1") return false;
  try {
    const store = await cookies();
    const v = store.get("dev_session")?.value;
    return v === "platform_admin" || v === "brand_admin" || v === "store_employee";
  } catch {
    return false;
  }
}

export async function getSession(): Promise<Awaited<ReturnType<typeof _realGetSession>>> {
  if (!isAuthConfigured()) {
    if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession short-circuit: not configured");
    return { data: null, error: null } as Awaited<ReturnType<typeof _realGetSession>>;
  }
  if (await isDevSession()) {
    if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession short-circuit: dev_session");
    return { data: null, error: null } as Awaited<ReturnType<typeof _realGetSession>>;
  }
  if (process.env.PERF_TEST_AUTH === "1") console.log("[auth] getSession calling real Neon Auth");
  return _realGetSession();
}

/**
 * Re-exported for the API route handler compatibility.
 * `GET` and `POST` from `auth.handler()` handle all Neon Auth endpoints.
 */
const authInstance = auth.handler();
export const { GET: handlersGET, POST: handlersPOST } = authInstance;

/**
 * Re-exported for middleware compatibility (edge runtime can't use Node-only auth).
 * The middleware uses `neonAuthMiddleware` from `@neondatabase/auth/next/server` directly.
 * This named export exists for call sites that import `auth` from this module.
 */
export { auth };
