//! GET /admin/crawler/active-jobs — paginated `pending|running` chapters
//! GET /admin/crawler/covers — paginated mangas missing a cover
//!
//! These are pure DB-derived reads that drive two of the three
//! backlog tables on the dashboard. The third (dead jobs) lives in
//! the [`super::dead_jobs`] module because it also exposes a write.

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

use crate::app::AppState;
use crate::auth::extractor::RequireAdmin;
use crate::error::AppResult;
use crate::repo;
use crate::repo::crawler::{ActiveJob, MissingCoverRow};

use super::default_limit;

pub(super) fn routes() -> Router<AppState> {
    Router::new()
        .route("/admin/crawler/active-jobs", get(list_active_jobs))
        .route("/admin/crawler/covers", get(list_covers))
}

/// Pagination + title-search params shared by the backlog list endpoints.
#[derive(Debug, Deserialize, Default)]
struct ListParams {
    #[serde(default)]
    search: Option<String>,
    #[serde(default = "default_limit")]
    limit: i64,
    #[serde(default)]
    offset: i64,
}

async fn list_active_jobs(
    State(state): State<AppState>,
    _admin: RequireAdmin,
    Query(params): Query<ListParams>,
) -> AppResult<Json<crate::api::pagination::PagedResponse<ActiveJob>>> {
    let limit = params.limit.clamp(1, 200);
    let offset = params.offset.max(0);
    let search = params.search.filter(|s| !s.trim().is_empty());
    let (items, total) =
        repo::crawler::list_active_jobs(&state.db, search.as_deref(), limit, offset).await?;
    Ok(Json(crate::api::pagination::PagedResponse::with_total(
        items, limit, offset, total,
    )))
}

async fn list_covers(
    State(state): State<AppState>,
    _admin: RequireAdmin,
    Query(params): Query<ListParams>,
) -> AppResult<Json<crate::api::pagination::PagedResponse<MissingCoverRow>>> {
    let limit = params.limit.clamp(1, 200);
    let offset = params.offset.max(0);
    let search = params.search.filter(|s| !s.trim().is_empty());
    let (items, total) =
        repo::crawler::list_missing_cover_mangas(&state.db, search.as_deref(), limit, offset)
            .await?;
    Ok(Json(crate::api::pagination::PagedResponse::with_total(
        items, limit, offset, total,
    )))
}
