use crate::config::AppSettings;
use anyhow::{Context, Result};
use sqlx::migrate::Migrator;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use sqlx::{Pool, Sqlite, SqlitePool};
use std::str::FromStr;
use std::time::Duration;
use tracing::info;

pub const MIGRATOR: Migrator = sqlx::migrate!("./migrations");

pub async fn initialize_db(app_settings: &AppSettings) -> Result<Pool<Sqlite>> {
    app_settings.ensure_default_directory()?;

    let options = SqliteConnectOptions::from_str(&app_settings.database_url())?
        .create_if_missing(true)
        .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal)
        .foreign_keys(true);

    let pool = SqlitePoolOptions::new()
        .max_connections(20)
        .min_connections(5)
        .acquire_timeout(Duration::from_secs(30))
        .idle_timeout(Duration::from_secs(600))
        .connect_with(options)
        .await?;

    MIGRATOR.run(&pool).await.with_context(|| "Database migrations failed")?;
    info!("Database migrations completed successfully");

    Ok(pool)
}

pub async fn create_pool(opts: SqliteConnectOptions) -> Result<SqlitePool> {
    let pool = SqlitePool::connect_with(opts).await?;

    Ok(pool)
}
