import { Pool, PoolClient } from 'pg';
import { logger } from '../services/logger';

// Singleton Pool – wird beim ersten Import erstellt
let pool: Pool | null = null;

export const getPool = (): Pool => {
  if (!pool) {
    const connectionString = process.env.DATABASE_URL;
    if (!connectionString) {
      throw new Error('DATABASE_URL environment variable is not set');
    }

    pool = new Pool({
      connectionString,
      // Supabase: SSL erforderlich in Production
      ssl: process.env.NODE_ENV === 'production'
        ? { rejectUnauthorized: false }
        : undefined,
      max: 10,                // Max. Verbindungen im Pool
      idleTimeoutMillis: 30000,
      connectionTimeoutMillis: 5000,
    });

    pool.on('error', (err) => {
      logger.error('Unexpected database pool error', { error: err });
    });

    logger.info('Database pool initialized');
  }
  return pool;
};

/**
 * Führt eine Query aus und gibt die Rows zurück.
 * Für einfache SELECT/INSERT ohne Transaction.
 */
export const query = async <T extends Record<string, unknown> = Record<string, unknown>>(
  text: string,
  params?: unknown[]
): Promise<T[]> => {
  const start = Date.now();
  const result = await getPool().query<T>(text, params);
  const duration = Date.now() - start;

  logger.debug('DB Query', {
    query: text.substring(0, 100),
    duration: `${duration}ms`,
    rows: result.rowCount,
  });

  return result.rows;
};

/**
 * Führt mehrere Queries in einer Transaction aus.
 * Rollback bei Fehler.
 */
export const withTransaction = async <T>(
  fn: (client: PoolClient) => Promise<T>
): Promise<T> => {
  const client = await getPool().connect();
  try {
    await client.query('BEGIN');
    const result = await fn(client);
    await client.query('COMMIT');
    return result;
  } catch (error) {
    await client.query('ROLLBACK');
    throw error;
  } finally {
    client.release();
  }
};

/**
 * Health Check – prüft ob DB erreichbar ist
 */
export const checkDbConnection = async (): Promise<boolean> => {
  try {
    await query('SELECT 1');
    return true;
  } catch (error) {
    logger.error('Database health check failed', { error });
    return false;
  }
};
