import React from 'react';
import { render, within } from '@testing-library/react';
import { TestData } from 'lib/test-utils/table';
import { GridTable } from '../../../base/table';
import { TableExtensions } from '../../../base/tableExtensions';
import { TableProps } from '../../../base/types';
import { TablePaginationExtension } from '../tablePaginationExtension';

TableExtensions.addExtension(TablePaginationExtension);

describe('TablePaginationExtension', () => {
    const data: TestData[] = [
        { name: 'test1', value: 2 },
        { name: 'test2', value: 1 },
    ];

    const defaultProps = {
        paginated: true,
        totalCount: 100,
        page: 1,
        pageSize: 10,
    };

    const renderTable = (props: Partial<TableProps<TestData>> = {}) =>
        render(<GridTable data={data} {...defaultProps} {...props} />);

    describe('GridTable "paginated" prop', () => {
        test('does not render Pagination when false', () => {
            const { queryByTestId } = renderTable({ paginated: false });

            const element = queryByTestId('SuitePagination');
            expect(element).not.toBeInTheDocument();
        });

        test('renders Pagination control when true', () => {
            const { getByTestId } = renderTable({ paginated: true });

            const element = getByTestId('SuitePagination');
            expect(element).toBeInTheDocument();

            const btn = getByTestId('SuitePagination-message');
            const btnText = `pagination_message{"from":"11","to":"20","total":"100"}`;

            expect(btn).toBeInTheDocument();
            expect(btn).toHaveTextContent(btnText);
        });

        test('renders only next/prev buttons on default variant', () => {
            const { getByTestId, queryByTestId } = renderTable();

            const shownArrows = ['prev', 'next'];
            const notShownArrows = ['first', 'last'];

            shownArrows.forEach((arrow) => {
                const arrowEl = getByTestId(`SuitePagination-arrow-${arrow}`);
                expect(arrowEl).toBeInTheDocument();
            });

            notShownArrows.forEach((arrow) => {
                const arrowEl = queryByTestId(`SuitePagination-arrow-${arrow}`);
                expect(arrowEl).not.toBeInTheDocument();
            });
        });

        test('renders first/last buttons when paginationVariant is "expanded"', () => {
            const { getByTestId } = renderTable({
                paginationVariant: 'expanded',
            });

            const shownArrows = ['first', 'prev', 'next', 'last'];

            shownArrows.forEach((arrow) => {
                const arrowEl = getByTestId(`SuitePagination-arrow-${arrow}`);
                expect(arrowEl).toBeInTheDocument();
            });
        });

        describe('loading', () => {
            test('renders pagination skeletons', () => {
                const { getByTestId } = renderTable({
                    paginationVariant: 'expanded',
                    loading: true,
                    totalCount: 0,
                });

                const element = getByTestId('SuitePagination');
                expect(within(element).getAllByTestId('SkeletonLoader').length).toBe(5);
            });

            test('does not render skeletons when totalCount > 0', () => {
                const { getByTestId } = renderTable({
                    paginationVariant: 'expanded',
                    loading: true,
                    totalCount: 1,
                });

                const element = getByTestId('SuitePagination');
                expect(within(element).queryAllByTestId('SkeletonLoader').length).toBe(0);

                const shownArrows = ['first', 'prev', 'next', 'last'];
                shownArrows.forEach((arrow) => {
                    const arrowEl = getByTestId(`SuitePagination-arrow-${arrow}`);
                    expect(arrowEl).toBeInTheDocument();
                });
            });
        });
    });
});
