use sqlx::PgPool;

use crate::error::Result;

pub trait AuditLogRepository: Send + Sync {
    /// Log an API request.
    fn log_request(
        &self,
        user_id: &str,
        api_key: &str,
        endpoint: &str,
        response: &str,
        error_count: i32,
        success: bool,
    ) -> impl std::future::Future<Output = Result<()>> + Send;
}

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

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

impl AuditLogRepository for PgAuditLogRepository {
    async fn log_request(
        &self,
        user_id: &str,
        api_key: &str,
        endpoint: &str,
        response: &str,
        error_count: i32,
        success: bool,
    ) -> Result<()> {
        sqlx::query(
            r#"
            INSERT INTO user_logs
                (created_at, query_user_id, query_api_key, query_request, query_response, query_error_count, query_success_status)
            VALUES (NOW(), $1, $2, $3, $4, $5, $6)
            "#,
        )
        .bind(user_id)
        .bind(api_key)
        .bind(endpoint)
        .bind(response)
        .bind(error_count)
        .bind(success)
        .execute(&self.pool)
        .await?;

        Ok(())
    }
}
