//! Shared pagination envelope for list endpoints.
//!
//! `total` is `Option<i64>` and is always serialised — `null` when the
//! handler hasn't computed it yet, a number once it has. The shape is fixed
//! across `/mangas`, `/chapters`, `/bookmarks`, etc. so consumers can
//! handle pagination uniformly.

use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct PageInfo {
    pub limit: i64,
    pub offset: i64,
    pub total: Option<i64>,
}

#[derive(Debug, Serialize)]
pub struct PagedResponse<T> {
    pub items: Vec<T>,
    pub page: PageInfo,
}

impl<T> PagedResponse<T> {
    pub fn new(items: Vec<T>, limit: i64, offset: i64) -> Self {
        Self {
            items,
            page: PageInfo { limit, offset, total: None },
        }
    }

    pub fn with_total(items: Vec<T>, limit: i64, offset: i64, total: i64) -> Self {
        Self {
            items,
            page: PageInfo { limit, offset, total: Some(total) },
        }
    }

    /// For handlers that compute `total` only on some pages (e.g. the first)
    /// and leave it `None` elsewhere.
    pub fn with_optional_total(
        items: Vec<T>,
        limit: i64,
        offset: i64,
        total: Option<i64>,
    ) -> Self {
        Self {
            items,
            page: PageInfo { limit, offset, total },
        }
    }
}
