//! Admin Users Handler
//!
//! Provides admin user management endpoints using proper database and auth abstractions

use crate::auth::middleware::RequireAuth;
use crate::auth::repository::AuthRepository;
use crate::database::Database;
use crate::database::connection::DatabaseConnection;
use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    response::Json,
};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use rustelo_core_lib::auth::{HasPermissions, Permission, Role, User};
use std::collections::HashMap;
use uuid::Uuid;
use validator::Validate;

#[derive(Debug, Serialize, Deserialize)]
pub struct UserResponse {
    pub id: String,
    pub email: String,
    pub username: String,
    pub display_name: Option<String>,
    pub roles: Vec<String>,
    pub is_active: bool,
    pub is_verified: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub last_login: Option<DateTime<Utc>>,
    pub avatar_url: Option<String>,
    pub two_factor_enabled: bool,
}

#[derive(Debug, Deserialize, Validate)]
pub struct CreateUserRequest {
    #[validate(email)]
    pub email: String,
    #[validate(length(min = 3, max = 50))]
    pub username: String,
    #[validate(length(min = 1, max = 100))]
    pub display_name: Option<String>,
    pub roles: Vec<String>,
    pub send_invitation: bool,
    #[validate(length(min = 8))]
    pub temporary_password: Option<String>,
    pub is_active: Option<bool>,
}

#[derive(Debug, Deserialize, Validate)]
pub struct UpdateUserRequest {
    #[validate(email)]
    pub email: Option<String>,
    #[validate(length(min = 3, max = 50))]
    pub username: Option<String>,
    #[validate(length(min = 1, max = 100))]
    pub display_name: Option<String>,
    pub roles: Option<Vec<String>>,
    pub is_active: Option<bool>,
    pub is_verified: Option<bool>,
    pub avatar_url: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct UserQuery {
    pub page: Option<u32>,
    pub limit: Option<u32>,
    pub search: Option<String>,
    pub is_active: Option<bool>,
    pub role: Option<String>,
    pub sort_by: Option<String>,
    pub sort_order: Option<String>,
    pub is_verified: Option<bool>,
}

#[derive(Debug, Serialize)]
pub struct UserListResponse {
    pub users: Vec<UserResponse>,
    pub total: u64,
    pub page: u32,
    pub limit: u32,
    pub total_pages: u32,
}

#[derive(Debug, Serialize)]
pub struct UserStatsResponse {
    pub total_users: u64,
    pub active_users: u64,
    pub inactive_users: u64,
    pub verified_users: u64,
    pub unverified_users: u64,
    pub recent_registrations: u64,
    pub two_factor_enabled: u64,
}

/// Get all users with pagination and filtering
pub async fn get_users(
    RequireAuth(user): RequireAuth,
    Query(query): Query<UserQuery>,
    State(db): State<Database>,
    State(auth_repo): State<AuthRepository>,
) -> Result<Json<UserListResponse>, StatusCode> {
    // Check admin permissions
    if !user.has_permission(Permission::ReadUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    let conn = db.pool().create_connection();
    let page = query.page.unwrap_or(1);
    let limit = query.limit.unwrap_or(20).min(100);
    let offset = (page - 1) * limit;

    // Build the query
    let users = get_users_with_filters(&conn, &query, limit, offset)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Get total count
    let total = get_users_count(&conn, &query)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    let total_pages = (total + limit as u64 - 1) / limit as u64;

    Ok(Json(UserListResponse {
        users,
        total,
        page,
        limit,
        total_pages: total_pages as u32,
    }))
}

/// Get a specific user by ID
pub async fn get_user(
    RequireAuth(user): RequireAuth,
    Path(user_id): Path<String>,
    State(auth_repo): State<AuthRepository>,
) -> Result<Json<UserResponse>, StatusCode> {
    // Check permissions - can read own profile or has read users permission
    let target_uuid = Uuid::parse_str(&user_id).map_err(|_| StatusCode::BAD_REQUEST)?;

    if user.id != target_uuid && !user.has_permission(Permission::ReadUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    let db_user = auth_repo
        .find_user_by_id(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
        .ok_or(StatusCode::NOT_FOUND)?;

    let roles = auth_repo
        .get_user_roles(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(UserResponse {
        id: db_user.id.to_string(),
        email: db_user.email,
        username: db_user.username.unwrap_or_default(),
        display_name: db_user.display_name,
        roles,
        is_active: db_user.is_active,
        is_verified: db_user.is_verified,
        created_at: db_user.created_at,
        updated_at: db_user.updated_at,
        last_login: db_user.last_login,
        avatar_url: db_user.avatar_url,
        two_factor_enabled: db_user.two_factor_enabled,
    }))
}

/// Create a new user
pub async fn create_user(
    RequireAuth(user): RequireAuth,
    State(db): State<Database>,
    State(auth_repo): State<AuthRepository>,
    Json(request): Json<CreateUserRequest>,
) -> Result<Json<UserResponse>, StatusCode> {
    // Check admin permissions
    if !user.has_permission(Permission::WriteUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    // Validate request
    request.validate().map_err(|_| StatusCode::BAD_REQUEST)?;

    let conn = db.pool().create_connection();

    // Check if user already exists
    if auth_repo
        .email_exists(&request.email)
        .await
        .unwrap_or(false)
    {
        return Err(StatusCode::CONFLICT);
    }

    if auth_repo
        .username_exists(&request.username)
        .await
        .unwrap_or(false)
    {
        return Err(StatusCode::CONFLICT);
    }

    // Validate roles exist
    for role_name in &request.roles {
        if !role_exists(&conn, role_name).await.unwrap_or(false) {
            return Err(StatusCode::BAD_REQUEST);
        }
    }

    // Generate password hash
    let password = request
        .temporary_password
        .unwrap_or_else(generate_temporary_password);

    let password_hash = bcrypt::hash(&password, bcrypt::DEFAULT_COST)
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Create user using auth repository
    let create_request = crate::database::auth::CreateUserRequest {
        email: request.email.clone(),
        password_hash,
        display_name: request.display_name.clone(),
        username: Some(request.username.clone()),
        is_verified: false,
        is_active: request.is_active.unwrap_or(true),
    };

    let created_user = auth_repo
        .create_user(&create_request)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Assign roles
    for role_name in &request.roles {
        auth_repo
            .add_user_role(&created_user.id, role_name)
            .await
            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    }

    // Log activity
    log_admin_activity(
        &conn,
        &user.id.to_string(),
        "create_user",
        "user",
        Some(&created_user.id.to_string()),
        None,
        None,
    )
    .await
    .ok();

    // Send invitation email if requested
    if request.send_invitation {
        // TODO: Implement email sending
        tracing::info!(
            "Would send invitation email to {} with temporary password",
            request.email
        );
    }

    // Return created user
    Ok(Json(UserResponse {
        id: created_user.id.to_string(),
        email: created_user.email,
        username: created_user.username.unwrap_or_default(),
        display_name: created_user.display_name,
        roles: request.roles,
        is_active: created_user.is_active,
        is_verified: created_user.is_verified,
        created_at: created_user.created_at,
        updated_at: created_user.updated_at,
        last_login: created_user.last_login,
        avatar_url: created_user.avatar_url,
        two_factor_enabled: created_user.two_factor_enabled,
    }))
}

/// Update a user
pub async fn update_user(
    RequireAuth(user): RequireAuth,
    Path(user_id): Path<String>,
    State(db): State<Database>,
    State(auth_repo): State<AuthRepository>,
    Json(request): Json<UpdateUserRequest>,
) -> Result<Json<UserResponse>, StatusCode> {
    let target_uuid = Uuid::parse_str(&user_id).map_err(|_| StatusCode::BAD_REQUEST)?;

    // Check permissions - can update own profile or has write users permission
    if user.id != target_uuid && !user.has_permission(Permission::WriteUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    // Validate request
    request.validate().map_err(|_| StatusCode::BAD_REQUEST)?;

    let conn = db.pool().create_connection();

    // Get existing user
    let mut existing_user = auth_repo
        .find_user_by_id(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
        .ok_or(StatusCode::NOT_FOUND)?;

    // Update fields
    if let Some(email) = &request.email {
        if email != &existing_user.email {
            if auth_repo.email_exists(email).await.unwrap_or(false) {
                return Err(StatusCode::CONFLICT);
            }
            existing_user.email = email.clone();
        }
    }

    if let Some(username) = &request.username {
        if Some(username) != existing_user.username.as_ref() {
            if auth_repo.username_exists(username).await.unwrap_or(false) {
                return Err(StatusCode::CONFLICT);
            }
            existing_user.username = Some(username.clone());
        }
    }

    if let Some(display_name) = &request.display_name {
        existing_user.display_name = Some(display_name.clone());
    }

    if let Some(is_active) = request.is_active {
        // Only admins can change active status
        if user.has_permission(Permission::WriteUsers) {
            existing_user.is_active = is_active;
        }
    }

    if let Some(is_verified) = request.is_verified {
        // Only admins can change verified status
        if user.has_permission(Permission::WriteUsers) {
            existing_user.is_verified = is_verified;
        }
    }

    if let Some(avatar_url) = &request.avatar_url {
        existing_user.avatar_url = Some(avatar_url.clone());
    }

    existing_user.updated_at = Utc::now();

    // Update user
    auth_repo
        .update_user(&existing_user)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Update roles if provided and user has permission
    if let Some(roles) = &request.roles {
        if user.has_permission(Permission::WriteUsers) {
            // Get current roles
            let current_roles = auth_repo
                .get_user_roles(&target_uuid)
                .await
                .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

            // Remove roles not in new list
            for role in &current_roles {
                if !roles.contains(role) {
                    auth_repo
                        .remove_user_role(&target_uuid, role)
                        .await
                        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
                }
            }

            // Add new roles
            for role in roles {
                if !current_roles.contains(role) {
                    if role_exists(&conn, role).await.unwrap_or(false) {
                        auth_repo
                            .add_user_role(&target_uuid, role)
                            .await
                            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
                    }
                }
            }
        }
    }

    // Log activity
    log_admin_activity(
        &conn,
        &user.id.to_string(),
        "update_user",
        "user",
        Some(&target_uuid.to_string()),
        None,
        None,
    )
    .await
    .ok();

    // Get updated roles
    let updated_roles = auth_repo
        .get_user_roles(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(UserResponse {
        id: existing_user.id.to_string(),
        email: existing_user.email,
        username: existing_user.username.unwrap_or_default(),
        display_name: existing_user.display_name,
        roles: updated_roles,
        is_active: existing_user.is_active,
        is_verified: existing_user.is_verified,
        created_at: existing_user.created_at,
        updated_at: existing_user.updated_at,
        last_login: existing_user.last_login,
        avatar_url: existing_user.avatar_url,
        two_factor_enabled: existing_user.two_factor_enabled,
    }))
}

/// Delete a user
pub async fn delete_user(
    RequireAuth(user): RequireAuth,
    Path(user_id): Path<String>,
    State(db): State<Database>,
    State(auth_repo): State<AuthRepository>,
) -> Result<StatusCode, StatusCode> {
    // Check admin permissions
    if !user.has_permission(Permission::DeleteUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    let target_uuid = Uuid::parse_str(&user_id).map_err(|_| StatusCode::BAD_REQUEST)?;

    // Prevent self-deletion
    if user.id == target_uuid {
        return Err(StatusCode::BAD_REQUEST);
    }

    let conn = db.pool().create_connection();

    // Check if user exists
    if auth_repo.find_user_by_id(&target_uuid).await.is_err() {
        return Err(StatusCode::NOT_FOUND);
    }

    // Delete user (this should cascade to sessions and roles)
    auth_repo
        .delete_user(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Log activity
    log_admin_activity(
        &conn,
        &user.id.to_string(),
        "delete_user",
        "user",
        Some(&target_uuid.to_string()),
        None,
        None,
    )
    .await
    .ok();

    Ok(StatusCode::NO_CONTENT)
}

/// Toggle user active status
pub async fn toggle_user_status(
    RequireAuth(user): RequireAuth,
    Path(user_id): Path<String>,
    State(db): State<Database>,
    State(auth_repo): State<AuthRepository>,
) -> Result<Json<UserResponse>, StatusCode> {
    // Check admin permissions
    if !user.has_permission(Permission::WriteUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    let target_uuid = Uuid::parse_str(&user_id).map_err(|_| StatusCode::BAD_REQUEST)?;

    // Prevent self-modification
    if user.id == target_uuid {
        return Err(StatusCode::BAD_REQUEST);
    }

    let conn = db.pool().create_connection();

    // Get current user
    let mut existing_user = auth_repo
        .find_user_by_id(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
        .ok_or(StatusCode::NOT_FOUND)?;

    // Toggle status
    existing_user.is_active = !existing_user.is_active;
    existing_user.updated_at = Utc::now();

    // Update user
    auth_repo
        .update_user(&existing_user)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // Invalidate all sessions if deactivating
    if !existing_user.is_active {
        auth_repo
            .invalidate_all_user_sessions(target_uuid)
            .await
            .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
    }

    // Log activity
    log_admin_activity(
        &conn,
        &user.id.to_string(),
        "toggle_user_status",
        "user",
        Some(&target_uuid.to_string()),
        None,
        None,
    )
    .await
    .ok();

    // Get roles for response
    let roles = auth_repo
        .get_user_roles(&target_uuid)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(UserResponse {
        id: existing_user.id.to_string(),
        email: existing_user.email,
        username: existing_user.username.unwrap_or_default(),
        display_name: existing_user.display_name,
        roles,
        is_active: existing_user.is_active,
        is_verified: existing_user.is_verified,
        created_at: existing_user.created_at,
        updated_at: existing_user.updated_at,
        last_login: existing_user.last_login,
        avatar_url: existing_user.avatar_url,
        two_factor_enabled: existing_user.two_factor_enabled,
    }))
}

/// Get user statistics
pub async fn get_user_stats(
    RequireAuth(user): RequireAuth,
    State(db): State<Database>,
) -> Result<Json<UserStatsResponse>, StatusCode> {
    // Check admin permissions
    if !user.has_permission(Permission::ReadUsers) {
        return Err(StatusCode::FORBIDDEN);
    }

    let conn = db.pool().create_connection();

    let stats = get_user_statistics(&conn)
        .await
        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(Json(stats))
}

// Helper functions

async fn get_users_with_filters(
    conn: &DatabaseConnection,
    query: &UserQuery,
    limit: u32,
    offset: u32,
) -> anyhow::Result<Vec<UserResponse>> {
    let mut sql = "SELECT u.id, u.email, u.username, u.display_name, u.is_active, u.is_verified, u.created_at, u.updated_at, u.last_login, u.avatar_url, u.two_factor_enabled FROM users u WHERE 1=1".to_string();
    let mut params = Vec::new();
    let mut param_index = 1;

    // Add search filter
    if let Some(search) = &query.search {
        let search_pattern = format!("%{}%", search);
        sql.push_str(&format!(
            " AND (u.email LIKE ${} OR u.username LIKE ${} OR u.display_name LIKE ${})",
            param_index,
            param_index + 1,
            param_index + 2
        ));
        params.push(search_pattern.clone().into());
        params.push(search_pattern.clone().into());
        params.push(search_pattern.into());
        param_index += 3;
    }

    // Add active filter
    if let Some(is_active) = query.is_active {
        sql.push_str(&format!(" AND u.is_active = ${}", param_index));
        params.push(is_active.into());
        param_index += 1;
    }

    // Add verified filter
    if let Some(is_verified) = query.is_verified {
        sql.push_str(&format!(" AND u.is_verified = ${}", param_index));
        params.push(is_verified.into());
        param_index += 1;
    }

    // Add role filter if provided
    if let Some(role) = &query.role {
        sql.push_str(&format!(" AND EXISTS (SELECT 1 FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = u.id AND r.name = ${})", param_index));
        params.push(role.into());
        param_index += 1;
    }

    // Add sorting
    let sort_by = query.sort_by.as_deref().unwrap_or("created_at");
    let sort_order = query.sort_order.as_deref().unwrap_or("desc");

    match sort_by {
        "email" | "username" | "display_name" | "created_at" | "updated_at" | "last_login" => {
            sql.push_str(&format!(" ORDER BY u.{} {}", sort_by, sort_order));
        }
        _ => {
            sql.push_str(" ORDER BY u.created_at DESC");
        }
    }

    // Add pagination
    sql.push_str(&format!(
        " LIMIT ${} OFFSET ${}",
        param_index,
        param_index + 1
    ));
    params.push((limit as i64).into());
    params.push((offset as i64).into());

    let rows = conn.fetch_all(&sql, &params).await?;
    let mut users = Vec::new();

    for row in rows {
        let user_id = Uuid::parse_str(&row.get_string("id")?)?;
        let roles = get_user_roles_by_id(conn, &user_id)
            .await
            .unwrap_or_default();

        users.push(UserResponse {
            id: row.get_string("id")?,
            email: row.get_string("email")?,
            username: row.get_optional_string("username")?.unwrap_or_default(),
            display_name: row.get_optional_string("display_name")?,
            roles,
            is_active: row.get_bool("is_active")?,
            is_verified: row.get_bool("is_verified")?,
            created_at: row.get_datetime("created_at")?,
            updated_at: row.get_datetime("updated_at")?,
            last_login: row.get_optional_datetime("last_login")?,
            avatar_url: row.get_optional_string("avatar_url")?,
            two_factor_enabled: row.get_bool("two_factor_enabled")?,
        });
    }

    Ok(users)
}

async fn get_users_count(conn: &DatabaseConnection, query: &UserQuery) -> anyhow::Result<u64> {
    let mut sql = "SELECT COUNT(*) as count FROM users u WHERE 1=1".to_string();
    let mut params = Vec::new();
    let mut param_index = 1;

    // Add same filters as get_users_with_filters but for counting
    if let Some(search) = &query.search {
        let search_pattern = format!("%{}%", search);
        sql.push_str(&format!(
            " AND (u.email LIKE ${} OR u.username LIKE ${} OR u.display_name LIKE ${})",
            param_index,
            param_index + 1,
            param_index + 2
        ));
        params.push(search_pattern.clone().into());
        params.push(search_pattern.clone().into());
        params.push(search_pattern.into());
        param_index += 3;
    }

    if let Some(is_active) = query.is_active {
        sql.push_str(&format!(" AND u.is_active = ${}", param_index));
        params.push(is_active.into());
        param_index += 1;
    }

    if let Some(is_verified) = query.is_verified {
        sql.push_str(&format!(" AND u.is_verified = ${}", param_index));
        params.push(is_verified.into());
        param_index += 1;
    }

    if let Some(role) = &query.role {
        sql.push_str(&format!(" AND EXISTS (SELECT 1 FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = u.id AND r.name = ${})", param_index));
        params.push(role.into());
    }

    let row = conn.fetch_one(&sql, &params).await?;
    Ok(row.get_i64("count")? as u64)
}

async fn get_user_roles_by_id(
    conn: &DatabaseConnection,
    user_id: &Uuid,
) -> anyhow::Result<Vec<String>> {
    let sql =
        "SELECT r.name FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = $1";
    let params = vec![user_id.to_string().into()];

    let rows = conn.fetch_all(sql, &params).await?;
    let mut roles = Vec::new();

    for row in rows {
        roles.push(row.get_string("name")?);
    }

    Ok(roles)
}

async fn role_exists(conn: &DatabaseConnection, role_name: &str) -> anyhow::Result<bool> {
    let sql = "SELECT COUNT(*) as count FROM roles WHERE name = $1";
    let params = vec![role_name.into()];

    let row = conn.fetch_one(sql, &params).await?;
    Ok(row.get_i64("count")? > 0)
}

async fn get_user_statistics(conn: &DatabaseConnection) -> anyhow::Result<UserStatsResponse> {
    let sql = match conn.database_type() {
        crate::database::DatabaseType::PostgreSQL => {
            "SELECT
                COUNT(*) as total_users,
                COUNT(CASE WHEN is_active = true THEN 1 END) as active_users,
                COUNT(CASE WHEN is_active = false THEN 1 END) as inactive_users,
                COUNT(CASE WHEN is_verified = true THEN 1 END) as verified_users,
                COUNT(CASE WHEN is_verified = false THEN 1 END) as unverified_users,
                COUNT(CASE WHEN created_at > NOW() - INTERVAL '30 days' THEN 1 END) as recent_registrations,
                COUNT(CASE WHEN two_factor_enabled = true THEN 1 END) as two_factor_enabled
             FROM users"
        }
        crate::database::DatabaseType::SQLite => {
            "SELECT
                COUNT(*) as total_users,
                COUNT(CASE WHEN is_active = 1 THEN 1 END) as active_users,
                COUNT(CASE WHEN is_active = 0 THEN 1 END) as inactive_users,
                COUNT(CASE WHEN is_verified = 1 THEN 1 END) as verified_users,
                COUNT(CASE WHEN is_verified = 0 THEN 1 END) as unverified_users,
                COUNT(CASE WHEN created_at > datetime('now', '-30 days') THEN 1 END) as recent_registrations,
                COUNT(CASE WHEN two_factor_enabled = 1 THEN 1 END) as two_factor_enabled
             FROM users"
        }
    };

    let row = conn.fetch_one(sql, &[]).await?;

    Ok(UserStatsResponse {
        total_users: row.get_i64("total_users")? as u64,
        active_users: row.get_i64("active_users")? as u64,
        inactive_users: row.get_i64("inactive_users")? as u64,
        verified_users: row.get_i64("verified_users")? as u64,
        unverified_users: row.get_i64("unverified_users")? as u64,
        recent_registrations: row.get_i64("recent_registrations")? as u64,
        two_factor_enabled: row.get_i64("two_factor_enabled")? as u64,
    })
}

fn generate_temporary_password() -> String {
    use rand::Rng;
    let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                         abcdefghijklmnopqrstuvwxyz\
                         0123456789\
                         !@#$%^&*";
    let mut rng = rand::thread_rng();

    (0..16)
        .map(|_| {
            let idx = rng.gen_range(0..charset.len());
            charset[idx] as char
        })
        .collect()
}

async fn log_admin_activity(
    conn: &DatabaseConnection,
    user_id: &str,
    action: &str,
    resource_type: &str,
    resource_id: Option<&str>,
    ip_address: Option<&str>,
    user_agent: Option<&str>,
) -> anyhow::Result<()> {
    let sql = match conn.database_type() {
        crate::database::DatabaseType::PostgreSQL => {
            "INSERT INTO activity_logs (id, user_id, action, resource_type, resource_id, ip_address, user_agent, timestamp, status)
             VALUES (gen_random_uuid(), $1, $2, $3, $4, $5, $6, NOW(), 'success')"
        }
        crate::database::DatabaseType::SQLite => {
            "INSERT INTO activity_logs (id, user_id, action, resource_type, resource_id, ip_address, user_agent, timestamp, status)
             VALUES (hex(randomblob(16)), $1, $2, $3, $4, $5, $6, datetime('now'), 'success')"
        }
    };

    let params = vec![
        user_id.into(),
        action.into(),
        resource_type.into(),
        resource_id.unwrap_or("").into(),
        ip_address.unwrap_or("").into(),
        user_agent.unwrap_or("").into(),
    ];

    conn.execute(sql, &params).await?;
    Ok(())
}
