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

const config = {
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    max: 10,
    idleTimeoutMillis: 30000,
    connectionTimeoutMillis: 5000
}

const pools = {
    data: new Pool({ ...config, database: process.env.DATA_DB }),
    sensors: new Pool({ ...config, database: process.env.SENSOR_DB || 'sensors' }),
}

Object.entries(pools).forEach(([name, pool]) => {
    pool.on('error', (err) => {
        console.error(`Error in ${name} pool`, err);
    })
});

/**
 * 
 * @param {'data' | 'sensors'} db - the name of the database 
 * @returns {Promise<import('pg').PoolClient>} 
 */
async function getClient(db) {
    const pool = pools[db];
    if (!pool) throw new Error(`Database pool type ${db} does not exist`);
    console.log(`Acquiring client for ${db} database... with config:`, config);
    return await pool.connect();
}

/**
 * Esegue una query sul database specificato
 * @param {string} text - Query SQL
 * @param {any[]} params - Parametri
 * @param {'data' | 'sensors'} name - Quale DB usare
 */
async function query(text, params, name = 'data') {
    const client = await getClient(name);
    try {
        return await client.query(text, params);
    } catch (error) {
        console.error(`[DB Query Error on ${name}]`, error.message);
        throw error;
    } finally {
        client.release();
    }
}

/**
 * Inserisce una riga in una tabella
 */
async function append(table, data, type = 'data') {
    const keys = Object.keys(data);
    const values = Object.values(data);
    const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');
    const columns = keys.join(', ');
    const sql = `INSERT INTO ${table} (${columns}) VALUES (${placeholders}) RETURNING *`;
    return await query(sql, values, type);
}

/**
 * Rimuove una riga
 */
async function remove(table, condition, params, type = 'data') {
    const sql = `DELETE FROM ${table} WHERE ${condition}`;
    return await query(sql, params, type);
}

async function checkPostgres() {
    const status = {};
    console.log("Checking PostgreSQL connections with config:", config);
    for (const [name, pool] of Object.entries(pools)) {
        try {
            await pool.query('SELECT NOW()');
            console.log(`PostgreSQL connection check successful for ${name}`);
            status[name] = 'connected';
        } catch (error) {
            console.log(`PostgreSQL connection check failed for ${name}:`, error.message);
            status[name] = 'disconnected';
        }
    }
    return status;
}
module.exports = {
    query,
    append,
    remove,
    getClient,
    checkPostgres,
    pools
};