import type { PoolConfig } from 'pg';
import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';
import { env } from '../config/env';
import { logger } from '../utils/logger';

/**
 * `?schema=` in DATABASE_URL is a Prisma URL extension. node-postgres does not apply it,
 * so connections default to `search_path=public`. PrismaPg also needs an explicit schema
 * option in some setups (see prisma/prisma#28611).
 */
function createPgPoolConfig(connectionString: string): { poolConfig: PoolConfig; prismaSchema?: string } {
  if (!connectionString) {
    return { poolConfig: { connectionString: '' } };
  }
  try {
    const url = new URL(connectionString);
    const schema = url.searchParams.get('schema')?.trim();
    const poolConfig: PoolConfig = { connectionString };
    if (schema) {
      const escaped = schema.replace(/"/g, '""');
      poolConfig.options = `-c search_path="${escaped}"`;
    }
    return { poolConfig, prismaSchema: schema || undefined };
  } catch {
    return { poolConfig: { connectionString } };
  }
}

const { poolConfig, prismaSchema } = createPgPoolConfig(env.DATABASE_URL);
const pool = new Pool(poolConfig);
const adapter = prismaSchema ? new PrismaPg(pool, { schema: prismaSchema }) : new PrismaPg(pool);

export const prisma = new PrismaClient({
  adapter,
  log: ['warn', 'error'],
});

export const connectDB = async () => {
  if (!env.DATABASE_URL) {
    logger.error('DATABASE_URL is not set. Please check your .env file.');
    process.exit(1);
  }

  try {
    // Adapter-based client connects when first used, 
    // but we can test the pool connection here.
    const client = await pool.connect();
    client.release();
    logger.info('Connected to PostgreSQL successfully via Driver Adapter.');
  } catch (error) {
    logger.error('Failed to connect to PostgreSQL:', error);
    if (error instanceof Error && error.message.includes('password')) {
      logger.error('Database authentication failed. Please check your DATABASE_URL password.');
    }
    process.exit(1);
  }
};
