const { paginate, parsePaginationParams, DEFAULT_LIMIT, MAX_LIMIT } = require('../src/utilities/pagination');

describe('Pagination — DashCaddy list endpoints', () => {

  describe('parsePaginationParams', () => {
    it('returns null when no pagination params (backward compat — full list)', () => {
      expect(parsePaginationParams({})).toBeNull();
      expect(parsePaginationParams({ search: 'plex' })).toBeNull();
    });

    it('parses page and limit from query', () => {
      const params = parsePaginationParams({ page: '2', limit: '10' });
      expect(params).toEqual({ page: 2, limit: 10 });
    });

    it('defaults page to 1', () => {
      expect(parsePaginationParams({ limit: '25' })).toEqual({ page: 1, limit: 25 });
    });

    it('defaults limit to DEFAULT_LIMIT when only page given', () => {
      expect(parsePaginationParams({ page: '3' })).toEqual({ page: 3, limit: DEFAULT_LIMIT });
    });

    it('clamps page to minimum 1', () => {
      expect(parsePaginationParams({ page: '0' }).page).toBe(1);
      expect(parsePaginationParams({ page: '-5' }).page).toBe(1);
    });

    it('treats limit 0 as default (parseInt falsy → DEFAULT_LIMIT)', () => {
      expect(parsePaginationParams({ limit: '0' }).limit).toBe(DEFAULT_LIMIT);
    });

    it('clamps negative limit to minimum 1', () => {
      expect(parsePaginationParams({ limit: '-10' }).limit).toBe(1);
    });

    it('clamps limit to MAX_LIMIT', () => {
      expect(parsePaginationParams({ limit: '9999' }).limit).toBe(MAX_LIMIT);
    });

    it('handles NaN gracefully', () => {
      const params = parsePaginationParams({ page: 'abc', limit: 'xyz' });
      expect(params.page).toBe(1);
      expect(params.limit).toBe(DEFAULT_LIMIT);
    });
  });

  describe('paginate', () => {
    const items = Array.from({ length: 55 }, (_, i) => ({ id: `svc-${i + 1}` }));

    it('returns all items when params is null (no pagination)', () => {
      const result = paginate(items, null);
      expect(result.data).toHaveLength(55);
      expect(result.pagination).toBeUndefined();
    });

    it('returns first page correctly', () => {
      const result = paginate(items, { page: 1, limit: 10 });
      expect(result.data).toHaveLength(10);
      expect(result.data[0].id).toBe('svc-1');
      expect(result.pagination.page).toBe(1);
      expect(result.pagination.total).toBe(55);
      expect(result.pagination.totalPages).toBe(6);
      expect(result.pagination.hasMore).toBe(true);
    });

    it('returns last page with fewer items', () => {
      const result = paginate(items, { page: 6, limit: 10 });
      expect(result.data).toHaveLength(5); // 55 - 50 = 5 remaining
      expect(result.data[0].id).toBe('svc-51');
      expect(result.pagination.hasMore).toBe(false);
    });

    it('returns empty array for page beyond total', () => {
      const result = paginate(items, { page: 100, limit: 10 });
      expect(result.data).toHaveLength(0);
      expect(result.pagination.hasMore).toBe(false);
    });

    it('handles empty list', () => {
      const result = paginate([], { page: 1, limit: 10 });
      expect(result.data).toHaveLength(0);
      expect(result.pagination.total).toBe(0);
      expect(result.pagination.totalPages).toBe(0);
    });

    it('single-page result when limit exceeds total', () => {
      const result = paginate(items, { page: 1, limit: 100 });
      expect(result.data).toHaveLength(55);
      expect(result.pagination.totalPages).toBe(1);
      expect(result.pagination.hasMore).toBe(false);
    });
  });

  describe('Real DashCaddy scenario: 52 app templates paginated', () => {
    const templates = Array.from({ length: 52 }, (_, i) => ({
      id: `app-${i}`,
      name: `App ${i}`,
      category: i < 10 ? 'Media' : 'Utilities'
    }));

    it('default limit (50) shows first 50 apps with hasMore', () => {
      const params = parsePaginationParams({ page: '1' });
      const result = paginate(templates, params);
      expect(result.data).toHaveLength(50);
      expect(result.pagination.hasMore).toBe(true);
    });

    it('page 2 shows remaining 2 apps', () => {
      const params = parsePaginationParams({ page: '2' });
      const result = paginate(templates, params);
      expect(result.data).toHaveLength(2);
      expect(result.pagination.hasMore).toBe(false);
    });
  });
});
