use serde::{Deserialize, Serialize};
use sqlx::{Any, Pool};
use crate::error::OrmError;
use crate::{SelectQuery};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Page<T> {
    pub data: Vec<T>,
    pub page_number: i64,
    pub total_rows: i64,
    pub total_pages: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pagination {
    pub page_number: i64,
    pub page_size: i64,
}

#[derive(sqlx::FromRow)]
pub struct TotalPagination {
    pub rows: i64,
}

pub async fn calculate_pagination(query: SelectQuery, pagination: Pagination, pool: &Pool<Any>) -> Result<TotalPagination, OrmError> {
    if pagination.page_number <= 0 {
        return Err(OrmError {
            message: "Page number must be a positive integer".to_string(),
        });
    }
    if pagination.page_size <= 0 {
        return Err(OrmError {
            message: "Page size must be a positive integer".to_string(),
        });
    }
    let limit = pagination.page_number * pagination.page_size;
    let offset = pagination.page_number - pagination.page_size;
    let mut query = query.clone();
    query = query.limit(limit);
    query = query.offset(offset);
    query.get_pagination_results_query(pool).await
}