import 'dotenv/config';
import { drizzle as drizzleSqlite } from 'drizzle-orm/better-sqlite3';
import { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';
import Database from 'better-sqlite3';
import pg from 'pg';
import * as schema from './schema.js';
import { existsSync, mkdirSync } from 'fs';
import { dirname } from 'path';

const dbType = process.env.DB_TYPE || 'sqlite';

let db: ReturnType<typeof drizzleSqlite> | ReturnType<typeof drizzlePg>;

if (dbType === 'postgres') {
  // Cap connections per instance so that, when running multiple replicas,
  // DB_POOL_MAX * replicas stays below the Postgres max_connections limit.
  const pool = new pg.Pool({
    connectionString: process.env.DATABASE_URL || 'postgresql://localhost:5432/spanglish',
    max: Number(process.env.DB_POOL_MAX || 10),
  });
  db = drizzlePg(pool, { schema });
} else {
  const dbPath = process.env.DATABASE_URL || './data/spanglish.db';
  
  // Ensure data directory exists
  const dir = dirname(dbPath);
  if (!existsSync(dir)) {
    mkdirSync(dir, { recursive: true });
  }
  
  const sqlite = new Database(dbPath);
  sqlite.pragma('journal_mode = WAL');
  db = drizzleSqlite(sqlite, { schema });
}

// ==================== Database Compatibility Helpers ====================
// These functions abstract the differences between SQLite and PostgreSQL Drizzle drivers:
// - SQLite uses .get() for single result, .all() for multiple
// - PostgreSQL returns arrays directly (no .get()/.all() methods)

/**
 * Get a single result from a query (works with both SQLite and PostgreSQL)
 * @param query - A Drizzle query builder (e.g., db.select().from(table).where(...))
 * @returns The first result or null
 */
export async function dbGet<T>(query: any): Promise<T | null> {
  if (dbType === 'postgres') {
    const results = await query;
    return results[0] || null;
  }
  // SQLite - use .get()
  return query.get() || null;
}

/**
 * Get all results from a query (works with both SQLite and PostgreSQL)
 * @param query - A Drizzle query builder (e.g., db.select().from(table).where(...))
 * @returns Array of results
 */
export async function dbAll<T>(query: any): Promise<T[]> {
  if (dbType === 'postgres') {
    return await query;
  }
  // SQLite - use .all()
  return query.all();
}

/**
 * Check if using PostgreSQL
 */
export function isPostgres(): boolean {
  return dbType === 'postgres';
}

/**
 * Check if using SQLite
 */
export function isSqlite(): boolean {
  return dbType === 'sqlite';
}

export { db, dbType };
export * from './schema.js';
