import { describe, it, expect, vi, afterEach } from 'vitest';
import { render, screen, cleanup } from '@testing-library/svelte';
import Pager from './Pager.svelte';

afterEach(() => cleanup());

describe('Pager', () => {
    it('renders nothing when totalPages <= 1', () => {
        const { container } = render(Pager, { props: { page: 1, totalPages: 1, onChange: () => {} } });
        expect(container.querySelector('nav')).toBeNull();
    });

    it('disables Prev on the first page and Next on the last', () => {
        const { rerender } = render(Pager, {
            props: { page: 1, totalPages: 5, onChange: () => {} }
        });
        expect((screen.getByRole('button', { name: /prev/i }) as HTMLButtonElement).disabled).toBe(true);
        expect((screen.getByRole('button', { name: /next/i }) as HTMLButtonElement).disabled).toBe(false);

        rerender({ page: 5, totalPages: 5, onChange: () => {} });
        expect((screen.getByRole('button', { name: /prev/i }) as HTMLButtonElement).disabled).toBe(false);
        expect((screen.getByRole('button', { name: /next/i }) as HTMLButtonElement).disabled).toBe(true);
    });

    it('marks the current page button as aria-current', () => {
        render(Pager, { props: { page: 3, totalPages: 5, onChange: () => {} } });
        const current = screen.getByRole('button', { name: /go to page 3/i });
        expect(current.getAttribute('aria-current')).toBe('page');
    });

    it('fires onChange with the clicked page number', async () => {
        const onChange = vi.fn();
        render(Pager, { props: { page: 1, totalPages: 5, onChange } });
        screen.getByRole('button', { name: /go to page 3/i }).click();
        expect(onChange).toHaveBeenCalledWith(3);
    });

    it('Prev decrements and Next increments via onChange', () => {
        const onChange = vi.fn();
        render(Pager, { props: { page: 3, totalPages: 5, onChange } });
        screen.getByRole('button', { name: /prev/i }).click();
        screen.getByRole('button', { name: /next/i }).click();
        expect(onChange).toHaveBeenNthCalledWith(1, 2);
        expect(onChange).toHaveBeenNthCalledWith(2, 4);
    });

    it('shows every page button when totalPages <= 7', () => {
        render(Pager, { props: { page: 4, totalPages: 7, onChange: () => {} } });
        for (let n = 1; n <= 7; n++) {
            expect(screen.getByRole('button', { name: new RegExp(`go to page ${n}$`, 'i') })).toBeTruthy();
        }
    });

    it('collapses middle pages with ellipsis when totalPages > 7 and current is in the middle', () => {
        render(Pager, { props: { page: 10, totalPages: 24, onChange: () => {} } });
        // First and last are always shown
        expect(screen.getByRole('button', { name: /go to page 1$/i })).toBeTruthy();
        expect(screen.getByRole('button', { name: /go to page 24$/i })).toBeTruthy();
        // Current and direct neighbours are shown
        expect(screen.getByRole('button', { name: /go to page 9$/i })).toBeTruthy();
        expect(screen.getByRole('button', { name: /go to page 10$/i })).toBeTruthy();
        expect(screen.getByRole('button', { name: /go to page 11$/i })).toBeTruthy();
        // Distant pages are NOT rendered as buttons
        expect(screen.queryByRole('button', { name: /go to page 2$/i })).toBeNull();
        expect(screen.queryByRole('button', { name: /go to page 23$/i })).toBeNull();
        // Ellipsis appears on both sides
        const ellipses = screen.getAllByText('…');
        expect(ellipses.length).toBeGreaterThanOrEqual(2);
    });

    it('does not duplicate boundary buttons when current is near the edge', () => {
        render(Pager, { props: { page: 2, totalPages: 20, onChange: () => {} } });
        // Each page button rendered should be unique — no duplicate "go to page 1"
        const first = screen.getAllByRole('button', { name: /go to page 1$/i });
        expect(first.length).toBe(1);
    });
});
