import pg from 'pg';

export function createPool(connectionString: string): pg.Pool {
  return new pg.Pool({
    connectionString,
    max: 20,
    idleTimeoutMillis: 30000,
    connectionTimeoutMillis: 5000,
  });
}

/**
 * Set tenant context on a pooled connection for RLS.
 * MUST be called before any query in a multi-tenant context.
 * MUST be cleared when returning the connection to the pool.
 */
export async function setTenantContext(client: pg.PoolClient, tenantId: string): Promise<void> {
  await client.query('SET LOCAL app.tenant_id = $1', [tenantId]);
}

/**
 * Clear tenant context — call this in a finally block before releasing the client.
 */
export async function clearTenantContext(client: pg.PoolClient): Promise<void> {
  await client.query('RESET app.tenant_id');
}

/**
 * Execute a query within a tenant-scoped transaction.
 * Handles SET LOCAL + RESET automatically to prevent RLS leakage via connection pooling.
 */
export async function withTenant<T>(
  pool: pg.Pool,
  tenantId: string,
  fn: (client: pg.PoolClient) => Promise<T>,
): Promise<T> {
  const client = await pool.connect();
  try {
    await client.query('BEGIN');
    await setTenantContext(client, tenantId);
    const result = await fn(client);
    await client.query('COMMIT');
    return result;
  } catch (err) {
    await client.query('ROLLBACK');
    throw err;
  } finally {
    await clearTenantContext(client);
    client.release();
  }
}
