import { MongoClient, Db } from "mongodb";

/**
 * Serverless-safe MongoDB client.
 *
 * A single MongoClient (and its connection pool) is cached on `globalThis` so
 * that, on Vercel/serverless, warm invocations and Next.js dev hot-reloads reuse
 * one pool instead of opening a new connection on every request (which would
 * exhaust Atlas connection limits — "connection storms"). The driver manages the
 * pool internally; we only ever hold one client promise per process.
 *
 * Server-only: this module reads MONGODB_URI (a secret) and must never be
 * imported into client components. It is used exclusively by server code
 * (route handlers, server actions, scripts).
 */

const DEFAULT_DB_NAME = "qutoai";

declare global {
  var __qutoMongoClientPromise: Promise<MongoClient> | undefined;
}

function clientPromise(): Promise<MongoClient> {
  const uri = process.env.MONGODB_URI;
  if (!uri) {
    throw new MongoNotConfiguredError();
  }
  if (!global.__qutoMongoClientPromise) {
    const client = new MongoClient(uri, {
      // Conservative pool for serverless: many concurrent lambdas each keep a
      // small pool; Atlas free tier caps total connections at 500.
      maxPoolSize: 10,
      minPoolSize: 0,
      retryWrites: true,
    });
    global.__qutoMongoClientPromise = client.connect();
  }
  return global.__qutoMongoClientPromise;
}

/** Thrown when MONGODB_URI is absent, so callers can distinguish config errors. */
export class MongoNotConfiguredError extends Error {
  constructor() {
    super("MONGODB_URI is not set. Configure it in .env.local / Vercel env.");
    this.name = "MongoNotConfiguredError";
  }
}

export function isMongoConfigured(): boolean {
  return Boolean(process.env.MONGODB_URI);
}

/**
 * Returns the application database. The database name comes from MONGODB_DB, or
 * the database embedded in the connection string, or a stable default — so a
 * single MONGODB_URI is enough to run locally and on Vercel.
 */
export async function getDb(): Promise<Db> {
  const client = await clientPromise();
  const name = process.env.MONGODB_DB?.trim() || DEFAULT_DB_NAME;
  return client.db(name);
}
