use sqlx::PgPool;

use crate::error::Result;
use crate::models::ApiKey;

pub trait ApiKeyRepository: Send + Sync {
    /// Load all API keys from the database.
    fn load_all(&self) -> impl std::future::Future<Output = Result<Vec<ApiKey>>> + Send;
}

#[derive(Clone)]
pub struct PgApiKeyRepository {
    pool: PgPool,
}

impl PgApiKeyRepository {
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }
}

impl ApiKeyRepository for PgApiKeyRepository {
    async fn load_all(&self) -> Result<Vec<ApiKey>> {
        let rows = sqlx::query_as::<_, (String, bool, String)>(
            "SELECT api_key_address, api_key_active_status, user_id FROM api_keys",
        )
        .fetch_all(&self.pool)
        .await?;

        Ok(rows
            .into_iter()
            .map(|(key, active, user_id)| ApiKey {
                key,
                active,
                user_id,
            })
            .collect())
    }
}
