import { PaginationDto, PaginationResult } from './paginationDto';

/**
 * paginate
 * --------
 * Generates a pagination metadata object based on total records
 * and optional pagination inputs.
 *
 * @param total Total number of records available
 * @param per_page Number of records per page (optional)
 * @param page Current page number (optional)
 * @returns PaginationResult containing pagination details
 */
export function paginate(
  total: number,
  per_page?: number,
  page?: number,
): PaginationResult {
  // Default number of items per page if not provided
  const perPage = 20;

  // Default current page if not provided
  const curPage = 1;

  /**
   * Calculate the last page number
   * Ensures total and per_page are treated as numbers
   */
  const lastPage = Math.ceil(Number(total) / Number(per_page || perPage));

  /**
   * Pagination metadata object
   * This is typically returned along with paginated data
   */
  const pagination = {
    total, // Total records count
    current_page: Number(page || curPage), // Current page number
    last_page: lastPage, // Last available page
    per_page: Number(per_page || perPage), // Records per page
  };

  return pagination;
}

/**
 * getSkipOffset
 * -------------
 * Calculates database pagination parameters (skip & take)
 * based on provided pagination filter.
 *
 * Commonly used with:
 * - TypeORM: skip & take
 * - SQL: OFFSET & LIMIT
 *
 * @param filter PaginationDto containing page and per_page values
 * @returns Tuple [skip, take]
 *   - skip: number of records to skip
 *   - take: number of records to fetch
 */
export function getSkipOffset(filter: PaginationDto): [number, number] {
  // Determine records per page (default: 5)
  const perPage = filter?.per_page ? filter?.per_page : 5;

  // Ensure page number is valid and greater than 0 (default: 1)
  const page = filter?.page && filter?.page > 0 ? filter?.page : 1;

  /**
   * skip = (currentPage - 1) * perPage
   * take = perPage
   */
  return [(page - 1) * perPage, perPage];
}
