import { drizzle as DrizzlePostgres } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { readConfigFile } from "@server/lib/readConfigFile";
import { withReplicas } from "drizzle-orm/pg-core";
import { build } from "@server/build";
import { db as mainDb, primaryDb as mainPrimaryDb } from "./driver";

function createLogsDb() {
    // Only use separate logs database in SaaS builds
    if (build !== "saas") {
        return mainDb;
    }

    const config = readConfigFile();

    // Merge configs, prioritizing private config
    const logsConfig = config.postgres_logs;

    // Check environment variable first
    let connectionString = process.env.POSTGRES_LOGS_CONNECTION_STRING;
    let replicaConnections: Array<{ connection_string: string }> = [];

    if (!connectionString && logsConfig) {
        connectionString = logsConfig.connection_string;
        replicaConnections = logsConfig.replicas || [];
    }

    // If POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS is set, use it
    if (process.env.POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS) {
        replicaConnections =
            process.env.POSTGRES_LOGS_REPLICA_CONNECTION_STRINGS.split(",").map(
                (conn) => ({
                    connection_string: conn.trim()
                })
            );
    }

    // If no logs database is configured, fall back to main database
    if (!connectionString) {
        return mainDb;
    }

    // Create separate connection pool for logs database
    const poolConfig = logsConfig?.pool || config.postgres?.pool;
    const primaryPool = new Pool({
        connectionString,
        max: poolConfig?.max_connections || 20,
        idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
        connectionTimeoutMillis: poolConfig?.connection_timeout_ms || 5000
    });

    const replicas = [];

    if (!replicaConnections.length) {
        replicas.push(
            DrizzlePostgres(primaryPool, {
                logger: process.env.QUERY_LOGGING == "true"
            })
        );
    } else {
        for (const conn of replicaConnections) {
            const replicaPool = new Pool({
                connectionString: conn.connection_string,
                max: poolConfig?.max_replica_connections || 20,
                idleTimeoutMillis: poolConfig?.idle_timeout_ms || 30000,
                connectionTimeoutMillis:
                    poolConfig?.connection_timeout_ms || 5000
            });
            replicas.push(
                DrizzlePostgres(replicaPool, {
                    logger: process.env.QUERY_LOGGING == "true"
                })
            );
        }
    }

    return withReplicas(
        DrizzlePostgres(primaryPool, {
            logger: process.env.QUERY_LOGGING == "true"
        }),
        replicas as any
    );
}

export const logsDb = createLogsDb();
export default logsDb;
export const primaryLogsDb = logsDb.$primary;
