import React from 'react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { ReportStatus, ReportType } from 'src/data/globalTypes';
import { ChangelogReport } from '../../../types';
import SongChangesTable from '../songChangesTable';
import { getReportTestData } from './fixtures';

const deleteChangelogReportMock = jest.fn();

jest.mock('src/data/mutations', () => ({
    useDeleteChangelogReport: () => ({
        deleteChangelogReport: deleteChangelogReportMock,
    }),
}));

describe('SongChangesTable', () => {
    const refetchMock = jest.fn();

    const renderTable = (data: ChangelogReport[]) =>
        renderInAppContext(
            <SongChangesTable
                reports={data}
                pageSize={10}
                page={0}
                totalCount={0}
                setPage={jest.fn()}
                setPageSize={jest.fn()}
                sortBy={[]}
                onSort={jest.fn()}
                loading={false}
                refetch={refetchMock}
            />
        );

    afterEach(() => {
        jest.restoreAllMocks();
    });

    test('It should render empty table', () => {
        const { getByTestId, getByText } = renderTable([]);
        expect(getByTestId('EmptyStateIllustration')).toBeInTheDocument();
        expect(getByText('No Reports Yet')).toBeInTheDocument();
    });

    test('It should render table with data', () => {
        const data: ChangelogReport[] = getReportTestData(
            ReportStatus.COMPLETE
        );
        const { getByText } = renderTable(data);
        expect(getByText('Update Delivery')).toBeInTheDocument();
        expect(getByText('09:35am EDT, 01 October 2024')).toBeInTheDocument();
        expect(
            getByText('All eligible as of 01 October 2024')
        ).toBeInTheDocument();
        expect(getByText('Test User')).toBeInTheDocument();
    });

    test('It should show a report with COMPLETE status', () => {
        const data: ChangelogReport[] = getReportTestData(
            ReportStatus.COMPLETE
        );
        const { getByText, getByTestId } = renderTable(data);
        expect(getByText('Update Delivery')).toBeInTheDocument();
        expect(getByTestId('TableActionButton-download')).toBeEnabled();
        expect(getByTestId('TableActionButton-delete')).toBeEnabled();
    });

    test('It should show a report with IN_PROGRESS status', () => {
        const data: ChangelogReport[] = getReportTestData(
            ReportStatus.IN_PROGRESS
        );
        const { getByText, getByTestId } = renderTable(data);
        expect(getByText('Update Delivery')).toBeInTheDocument();
        expect(getByTestId('InProgressGlyphIcon')).toBeInTheDocument();
        expect(getByTestId('TableActionButton-download')).toBeDisabled();
        expect(getByTestId('TableActionButton-delete')).toBeDisabled();
    });

    test('It should show a report with ERROR status', () => {
        const data: ChangelogReport[] = getReportTestData(ReportStatus.ERROR);
        const { getByText, getByTestId } = renderTable(data);
        expect(getByText('Update Delivery')).toBeInTheDocument();
        expect(getByTestId('WarningGlyphIcon')).toBeInTheDocument();
        expect(getByTestId('TableActionButton-download')).toBeDisabled();
        expect(getByTestId('TableActionButton-delete')).toBeEnabled();
    });

    test('It should delete a report', async () => {
        const data: ChangelogReport[] = getReportTestData(
            ReportStatus.COMPLETE
        );
        const { getByText, getByTestId } = renderTable(data);
        expect(getByText('Update Delivery')).toBeInTheDocument();
        expect(getByTestId('TableActionButton-download')).toBeEnabled();

        const deleteButton = getByTestId('TableActionButton-delete');
        expect(deleteButton).toBeEnabled();

        await deleteButton.click();
        expect(deleteChangelogReportMock).toHaveBeenCalled();
        expect(deleteChangelogReportMock).toHaveBeenCalledWith({
            variables: { id: 1 },
        });

        expect(refetchMock).toHaveBeenCalled();
    });

    test('It should show Time Period with -', async () => {
        const data: ChangelogReport[] = getReportTestData(ReportStatus.ERROR);

        const { getByText } = renderTable(data);
        expect(getByText('-')).toBeInTheDocument();
    });

    test('It should show Time Period with date range', async () => {
        const data: ChangelogReport[] = [
            {
                ...getReportTestData(ReportStatus.COMPLETE)[0],
                type: ReportType.ADHOC_WRITER,
            },
        ];

        const { getByText } = renderTable(data);
        expect(
            getByText('01 October 2024 - 02 October 2024')
        ).toBeInTheDocument();
    });

    test('It should show Time Period with All eligible as of', async () => {
        const data: ChangelogReport[] = getReportTestData(
            ReportStatus.COMPLETE
        );

        const { getByText } = renderTable(data);
        expect(
            getByText('All eligible as of 01 October 2024')
        ).toBeInTheDocument();
    });
});
