export type PaginatedResponseOptions = {
  page: number;
  limit: number;
  total: number;
  offset: number;
  currentCursor?: string | null;
  nextCursor?: string | null;
  mode?: 'offset' | 'cursor';
};

export type PaginatedResponse<T> = {
  items: T[];
  count: number;
  page: number;
  limit: number;
  total: number;
  totalPages: number;
  nextCursor: string | null;
  pagination: {
    mode: 'offset' | 'cursor';
    page: number;
    limit: number;
    count: number;
    total: number;
    totalPages: number;
    hasNextPage: boolean;
    hasPreviousPage: boolean;
    nextPage: number | null;
    previousPage: number | null;
    currentCursor: string | null;
    nextCursor: string | null;
  };
};

export const buildPaginatedResponse = <T>(
  items: T[],
  options: PaginatedResponseOptions,
): PaginatedResponse<T> => {
  const count = items.length;
  const totalPages = Math.ceil(options.total / options.limit) || 1;
  const hasNextPage = options.offset + count < options.total;
  const hasPreviousPage = options.offset > 0;
  const mode =
    options.mode ??
    (options.currentCursor !== undefined || options.nextCursor !== undefined ? 'cursor' : 'offset');

  return {
    items,
    count,
    page: options.page,
    limit: options.limit,
    total: options.total,
    totalPages,
    nextCursor: options.nextCursor ?? null,
    pagination: {
      mode,
      page: options.page,
      limit: options.limit,
      count,
      total: options.total,
      totalPages,
      hasNextPage,
      hasPreviousPage,
      nextPage: hasNextPage ? options.page + 1 : null,
      previousPage: hasPreviousPage ? Math.max(1, options.page - 1) : null,
      currentCursor: options.currentCursor ?? null,
      nextCursor: options.nextCursor ?? null,
    },
  };
};
