const { Pool } = require("pg");

let pool = null;

/**
 * Get or create a PostgreSQL connection pool.
 * Uses connection pooling optimized for Lambda:
 * - Reuses connections across invocations (when container is warm)
 * - Small pool size to avoid exhausting database connections
 *
 * Expects DATABASE_URL environment variable in format:
 * postgresql://user:password@host:port/database
 */
function getPool() {
  if (!pool) {
    const connectionString = process.env.DATABASE_URL;

    if (!connectionString) {
      throw new Error("DATABASE_URL environment variable is required");
    }

    pool = new Pool({
      connectionString,
      // Lambda-optimized settings
      max: 1, // Single connection per Lambda instance
      idleTimeoutMillis: 120000, // 2 minutes - keep connection warm
      connectionTimeoutMillis: 5000, // 5 seconds to connect
    });

    // Handle pool errors
    pool.on("error", (err) => {
      console.error("Unexpected database pool error:", err);
      pool = null; // Reset pool on error
    });
  }

  return pool;
}

/**
 * Execute a query with automatic connection management.
 * @param {string} text - SQL query text
 * @param {Array} params - Query parameters
 * @returns {Promise<object>} Query result
 */
async function query(text, params) {
  const pool = getPool();
  const start = Date.now();

  try {
    const result = await pool.query(text, params);
    const duration = Date.now() - start;

    console.log(JSON.stringify({
      level: "debug",
      message: "Executed query",
      query: text.substring(0, 100),
      duration,
      rows: result.rowCount,
    }));

    return result;
  } catch (error) {
    console.error(JSON.stringify({
      level: "error",
      message: "Query failed",
      query: text.substring(0, 100),
      error: error.message,
    }));
    throw error;
  }
}

/**
 * Close the connection pool (for cleanup).
 * Call this at the end of Lambda execution if needed.
 */
async function closePool() {
  if (pool) {
    await pool.end();
    pool = null;
  }
}

module.exports = {
  getPool,
  query,
  closePool,
};
