import { describe, it, expect } from 'vitest';
import { pageGetNextPageParam } from './paging';
import type { Page } from './types';

function mkPage<T>(items: T[], offset: number, total: number, limit = 50): Page<T> {
  return { items, offset, total, limit };
}

describe('pageGetNextPageParam', () => {
  it('returns next offset (offset + items.length) when more items remain', () => {
    const next = pageGetNextPageParam<number>();
    const last = mkPage([1, 2, 3, 4, 5], 0, 12);
    expect(next(last)).toBe(5);
  });

  it('returns next offset accounting for prior offset', () => {
    const next = pageGetNextPageParam<number>();
    const last = mkPage([1, 2, 3], 50, 100);
    expect(next(last)).toBe(53);
  });

  it('returns undefined when loaded reaches total', () => {
    const next = pageGetNextPageParam<number>();
    const last = mkPage([1, 2, 3], 7, 10);
    expect(next(last)).toBeUndefined();
  });

  it('returns undefined when last page is empty and offset already equals total', () => {
    const next = pageGetNextPageParam<number>();
    const last = mkPage<number>([], 10, 10);
    expect(next(last)).toBeUndefined();
  });

  it('returns undefined when loaded exceeds total (defensive)', () => {
    const next = pageGetNextPageParam<number>();
    const last = mkPage([1, 2, 3], 9, 10);
    expect(next(last)).toBeUndefined();
  });

  it('works for different element types via generic parameter', () => {
    const next = pageGetNextPageParam<string>();
    const last = mkPage(['a', 'b'], 0, 5);
    expect(next(last)).toBe(2);
  });
});
