//! GET /admin/audit — paginated, filterable admin-action audit log.
//!
//! A pure DB read over the `admin_audit` table joined to the actor's
//! username. Drives the "Audit" admin tab: who did what, when. Every
//! mutating admin action writes a row here; this is the only reader.

use axum::extract::{Query, State};
use axum::routing::get;
use axum::{Json, Router};
use serde::Deserialize;
use uuid::Uuid;

use crate::app::AppState;
use crate::auth::extractor::RequireAdmin;
use crate::error::AppResult;
use crate::repo;
use crate::repo::admin_audit::{AuditEntryRow, AuditFilter};

// Reuse the analysis window helper so `days` clamps identically everywhere.
use crate::api::admin::analysis::window_since;

pub fn routes() -> Router<AppState> {
    Router::new().route("/admin/audit", get(list_audit))
}

fn default_limit() -> i64 {
    50
}

#[derive(Debug, Deserialize, Default)]
struct AuditParams {
    #[serde(default)]
    action: Option<String>,
    #[serde(default)]
    target_kind: Option<String>,
    #[serde(default)]
    actor_user_id: Option<Uuid>,
    #[serde(default)]
    days: i64,
    #[serde(default = "default_limit")]
    limit: i64,
    #[serde(default)]
    offset: i64,
}

async fn list_audit(
    State(state): State<AppState>,
    _admin: RequireAdmin,
    Query(params): Query<AuditParams>,
) -> AppResult<Json<crate::api::pagination::PagedResponse<AuditEntryRow>>> {
    let limit = params.limit.clamp(1, 200);
    let offset = params.offset.max(0);
    let action = params.action.filter(|s| !s.trim().is_empty());
    let target_kind = params.target_kind.filter(|s| !s.trim().is_empty());
    let (items, total) = repo::admin_audit::list(
        &state.db,
        AuditFilter {
            action: action.as_deref(),
            target_kind: target_kind.as_deref(),
            actor_user_id: params.actor_user_id,
            since: window_since(params.days),
        },
        limit,
        offset,
    )
    .await?;
    Ok(Json(crate::api::pagination::PagedResponse::with_total(
        items, limit, offset, total,
    )))
}
