import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import { accountingPeriodList } from 'src/__fixtures__/graphql/accounting-period';
import * as accountingPeriodQuery from 'src/apollo/queries/accounting-period';
import AccountingPeriodList from 'src/components/accounting-period-list/accounting-period-list';
import { ABACUS_PROFILE, USER_FEATURES } from 'src/constants';

describe('<AccountingPeriodList>', () => {
    let periodListRequestSpy: any;
    let mockFeatures = {
        [USER_FEATURES.ABACUS_ACCOUNTING_PERIOD_DETAIL_MIGRATE_TO_TSX]: false,
    };
    const render = (features: { [x: number]: boolean } = mockFeatures) =>
        renderInAppContext(<AccountingPeriodList />, {
            identity: createIdentity({
                features,
                profileType: ABACUS_PROFILE,
                id: 'Jane User',
            }),
        });

    beforeEach(() => {
        periodListRequestSpy = jest
            .spyOn(accountingPeriodQuery, 'useAccountingPeriodList')
            .mockReturnValue({
                data: accountingPeriodList,
                error: undefined,
                loading: false,
            });
    });

    afterEach(jest.restoreAllMocks);

    it('renders', () => {
        const container = render();
        expect(container).toBeDefined();
    });

    it('requests a list of accounting periods on render', () => {
        render();
        expect(periodListRequestSpy).toHaveBeenCalled();
    });

    it('renders a list of accounting periods', async () => {
        const bodyText: any = [];
        render();
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            'Distribution',
            'Oct 2020',
            'September 2020',
            '261',
            '2020-09-30',
            'Open',
            'Performer Neighbouring Rights',
            'Sep 2020',
            'September 2020',
            '261',
            '2020-09-30',
            'Closed 2020-12-07',
        ]);
    });

    it('shows the table headers for accounting period table', () => {
        render();
        const tableHeaders = [
            'Contract Type',
            'Name',
            'Statement Period',
            'Statement Period ID',
            'Contract End Date',
            'Status',
        ];
        tableHeaders.forEach((header: any) =>
            expect(screen.getAllByText(header)).toBeDefined()
        );
    });

    it('renders new accounting period form on button click', () => {
        render();
        const button = screen.getByText('+ New Accounting Period');
        fireEvent.click(button);
        expect(screen.getAllByText('Contract Type')).toBeDefined();
        expect(screen.getByText('Period Name')).toBeDefined();
        expect(screen.getAllByText('Statement Period')).toBeDefined();
        expect(screen.getByText('Cancel')).toBeDefined();
        expect(screen.getByText('Create')).toBeDefined();

        expect(screen.queryByTestId('AccountingPeriodFormModal')).toBeNull();
    });

    it('renders new accounting period form on button click when FF is enabled', () => {
        mockFeatures = {
            [USER_FEATURES.ABACUS_ACCOUNTING_PERIOD_DETAIL_MIGRATE_TO_TSX]: true,
        };
        render(mockFeatures);
        const button = screen.getByText('+ New Accounting Period');
        fireEvent.click(button);
        expect(screen.getAllByText('Contract Type')).toBeDefined();
        expect(screen.getByText('Period Name')).toBeDefined();
        expect(screen.getAllByText('Statement Period')).toBeDefined();
        expect(screen.getByText('cancel')).toBeDefined();
        expect(screen.getByText('Create')).toBeDefined();

        expect(screen.getByTestId('AccountingPeriodFormModal')).toBeDefined();
    });
});
