import { OperationOk } from "@gnu-taler/taler-util";

export type PaginatedResult<T> = OperationOk<T> & {
  loadNext?(): void;
  loadFirst?(): void;
};

/**
 * 
 * @param data the result of the requested list
 * @param offset offset id or index
 * @param setOffset function to be call on loadNext or loadFirst to specify the new offset
 * @param getId return the offset id of a row
 * @param PAGINATED_LIST_REQUEST the limit of the request, the UI is expted to show N -1 elements
 * @returns an OperationOk with two function. If the function is missing is because the offset is on the limit
 */
export function buildPaginatedResult<R, OffId>(
  data: R[],
  offset: OffId | undefined,
  setOffset: (o: OffId | undefined) => void,
  getId: (r: R) => OffId,
  PAGINATED_LIST_REQUEST: number
): PaginatedResult<R[]> {
  const isLastPage = data.length < PAGINATED_LIST_REQUEST;
  const isFirstPage = offset === undefined;

  const result = structuredClone(data);
  
  if (result.length == PAGINATED_LIST_REQUEST) {
    result.pop();
  }
  return {
    type: "ok",
    case: "ok",
    body: result,
    loadNext: isLastPage
      ? undefined
      : () => {
          if (!result.length) return;
          const id = getId(result[result.length - 1]);
          setOffset(id);
        },
    loadFirst: isFirstPage
      ? undefined
      : () => {
          setOffset(undefined);
        },
  };
}
