/**
 * MongoDB Native Driver — client singleton
 *
 * Emits a small connection module shared by all controllers and services.
 * Collection naming convention: lowercase + 's' suffix (User → users,
 * Category → categorys), matching the lowercase-pluralized scheme declared
 * in the factory yaml. Models with custom collection names can override
 * via spec — the controller-generator looks at `model.storage?.collection`.
 */
import type { TemplateContext } from '@specverse/types';

export default function generateMongoClient(_context: TemplateContext): string {
  return `/**
 * MongoDB native driver — singleton client + helpers.
 *
 * Picks up MONGODB_URI / MONGODB_DB from the environment. The client is
 * lazily initialised on first use and reused across requests; \`disconnect\`
 * is exposed for graceful-shutdown wiring.
 */
import { MongoClient, type Db, type Collection, type Document } from 'mongodb';

const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017';
const dbName = process.env.MONGODB_DB || 'specverse';

let client: MongoClient | null = null;
let database: Db | null = null;

export async function getDb(): Promise<Db> {
  if (database) return database;
  client = new MongoClient(uri);
  await client.connect();
  database = client.db(dbName);
  return database;
}

export async function getCollection<T extends Document = Document>(
  name: string,
): Promise<Collection<T>> {
  const db = await getDb();
  return db.collection<T>(name);
}

export async function disconnect(): Promise<void> {
  if (client) {
    await client.close();
    client = null;
    database = null;
  }
}
`;
}
