import { fireEvent, render } from '@testing-library/react';
import ReleaseScheduleTable from '../release-schedule-table';
import type { StaggeredReleaseSchedule, TimedReleaseSchedule } from 'src/types';
import type { ReleaseScheduleTableProps } from '../release-schedule-table';

describe('<ReleaseScheduleTable>', () => {
    const timedReleaseSchedule: TimedReleaseSchedule[] = [
        {
            saleDateTime: '2022-02-21T13:50:00Z',
            deliveryStore: {
                id: '386',
                name: 'Spotify',
            },
        },
        {
            saleDateTime: '2022-02-21T13:50:00Z',
            deliveryStore: {
                id: '1',
                name: 'iTunes/Apple',
            },
        },
    ];

    const staggeredReleaseSchedule: StaggeredReleaseSchedule[] = [
        {
            saleDate: '2022-02-21',
            deliveryStore: {
                id: '386',
                name: 'Spotify',
            },
        },
        {
            saleDate: '2022-02-21',
            deliveryStore: {
                id: '1',
                name: 'iTunes/Apple',
            },
        },
    ];

    const defaultProps: ReleaseScheduleTableProps = {
        editable: true,
        releaseSchedule: [...timedReleaseSchedule],
    };

    const renderComponent = (props: Partial<ReleaseScheduleTableProps> = {}) =>
        render(<ReleaseScheduleTable {...defaultProps} {...props} />);

    describe('timed releases', () => {
        test('matches snapshot', () => {
            const { container } = renderComponent();
            expect(container).toMatchSnapshot();
        });
    });

    describe('staggered releases', () => {
        test('matches snapshot', () => {
            const { container } = renderComponent({
                releaseSchedule: staggeredReleaseSchedule,
            });
            expect(container).toMatchSnapshot();
        });

        test('sale time value represents staggered', () => {
            const { queryAllByText } = renderComponent({
                releaseSchedule: staggeredReleaseSchedule,
            });
            const saleTimeValue = queryAllByText(
                $t('releaseScheduler.releaseScheduleTable.staggeredSaleTime')
            )[0];
            expect(saleTimeValue).toBeInTheDocument();
        });
    });

    describe('service header', () => {
        test('service message is present', () => {
            const { queryByText } = renderComponent({
                releaseSchedule: staggeredReleaseSchedule,
            });
            const tableCount = queryByText(
                $t('releaseScheduler.releaseScheduleTable.scheduledReleases')
            );
            expect(tableCount).toBeInTheDocument();
        });
    });

    describe('remove selection button', () => {
        describe('all selected and remove clicked', () => {
            test('calls onRemove', () => {
                const onRemove = jest.fn();
                const { container } = renderComponent({ onRemove });
                const columnHeaders = container.getElementsByClassName(
                    'GridTable-header-row'
                )[0];
                const selectAll =
                    columnHeaders.getElementsByTagName('input')[0];
                fireEvent.click(selectAll);
                const tableBulkActions =
                    container.getElementsByClassName('TableBulkActions')[0];
                const removeAll =
                    tableBulkActions.getElementsByTagName('button')[0];
                fireEvent.click(removeAll);
                expect(onRemove).toHaveBeenCalledWith(timedReleaseSchedule);
            });
        });

        describe('one selected and remove clicked', () => {
            test('calls onRemove', () => {
                const onRemove = jest.fn();
                const { container } = renderComponent({ onRemove });
                const tableBody =
                    container.getElementsByClassName('GridTable-body')[0];
                const checkboxCell = tableBody.getElementsByClassName(
                    'cell-table-selection'
                )[0];
                const select = checkboxCell.getElementsByTagName('input')[0];
                fireEvent.click(select);
                const tableBulkActions =
                    container.getElementsByClassName('TableBulkActions')[0];
                const removeAll =
                    tableBulkActions.getElementsByTagName('button')[0];
                fireEvent.click(removeAll);
                expect(onRemove).toHaveBeenCalledWith([
                    timedReleaseSchedule[0],
                ]);
            });
        });
    });

    describe('remove button', () => {
        const [toRemove] = timedReleaseSchedule;
        describe('clicked', () => {
            test('calls onRemove with deliveryStore from row', () => {
                const onRemove = jest.fn();
                const { getAllByTestId } = renderComponent({ onRemove });
                const remove = getAllByTestId('TableActionButton-delete')[0];
                fireEvent.click(remove);
                expect(onRemove).toHaveBeenCalledWith(toRemove);
            });
        });
    });

    describe('emtpy table', () => {
        test('renders empty icon', () => {
            const { getByTestId } = renderComponent({ releaseSchedule: [] });
            expect(getByTestId('emtpy-table-icon')).toBeInTheDocument();
        });

        describe('manage button', () => {
            test('provided', () => {
                const buttonText = "I'm not a button";
                const manageButton = <div>{buttonText}</div>;
                const { getByText } = renderComponent({
                    releaseSchedule: [],
                    manageButton,
                });
                expect(getByText(buttonText)).toBeInTheDocument();
            });

            test('not provided', () => {
                const { getByText } = renderComponent({ releaseSchedule: [] });
                const emptyTableText = getByText(
                    $t('releaseScheduler.releaseScheduleTable.emptySchedule')
                );
                expect(emptyTableText).toBeInTheDocument();
            });
        });
    });
});
