//! Database initialization and connection management
//!
//! This module handles database connection setup, including support for both
//! PostgreSQL and SQLite databases with automatic type detection.

#[cfg(any(feature = "auth", feature = "content-db"))]
use crate::database::{Database, DatabaseConfig, DatabasePool};

/// Initialize database connection (if database features are enabled)
#[cfg(any(feature = "auth", feature = "content-db"))]
pub async fn initialize_database(
    config: &Config,
) -> Result<(Database, sqlx::PgPool, DatabasePool), Box<dyn std::error::Error>> {
    let database_config = DatabaseConfig {
        url: config.database.url.clone(),
        max_connections: config.database.max_connections,
        min_connections: config.database.min_connections,
        connect_timeout: std::time::Duration::from_secs(config.database.connect_timeout),
        idle_timeout: std::time::Duration::from_secs(config.database.idle_timeout),
        max_lifetime: std::time::Duration::from_secs(config.database.max_lifetime),
    };

    tracing::info!("Connecting to database: {}", database_config.url);

    let database_pool = DatabasePool::new(&database_config).await.map_err(|e| {
        tracing::error!("Failed to connect to database: {}", e);
        std::process::exit(1);
    })?;

    let db_type = database_pool.database_type();
    tracing::info!("Database type detected: {:?}", db_type);

    let database = Database::new(database_pool.clone());

    // For backward compatibility with existing code that expects PgPool
    #[cfg(feature = "auth")]
    let pool = match &database_pool {
        DatabasePool::PostgreSQL(pg_pool) => pg_pool.clone(),
        DatabasePool::SQLite(_) => {
            tracing::info!("Using SQLite database with database-agnostic auth system");
            // Create a dummy PgPool for compatibility (will be replaced gradually)
            sqlx::postgres::PgPoolOptions::new()
                .max_connections(1)
                .connect("postgres://dummy:dummy@localhost/dummy")
                .await
                .unwrap_or_else(|_| {
                    tracing::warn!("Could not create dummy PostgreSQL pool for compatibility");
                    tracing::info!("Auth services will use database-agnostic implementation");
                    std::process::exit(0); // Exit gracefully for now
                })
        }
    };

    #[cfg(not(feature = "auth"))]
    let pool = match &database_pool {
        DatabasePool::PostgreSQL(pg_pool) => pg_pool.clone(),
        DatabasePool::SQLite(_) => {
            // Create a dummy pool that won't be used
            sqlx::postgres::PgPoolOptions::new()
                .max_connections(1)
                .connect("postgres://dummy:dummy@localhost/dummy")
                .await
                .unwrap_or_else(|_| std::process::exit(1))
        }
    };

    Ok((database, pool, database_pool))
}

#[cfg(feature = "content-db")]
pub fn initialize_content_services(
    database_pool: &DatabasePool,
) -> std::sync::Arc<crate::content::ContentService> {
    use crate::content::{ContentRepository, ContentService, ContentSource};
    use std::sync::Arc;

    let content_repository = Arc::new(ContentRepository::from_pool(database_pool));
    Arc::new(
        ContentService::new(content_repository)
            .with_source(ContentSource::Database)
            .with_cache(true),
    )
}
