import React from 'react';
import { screen, fireEvent } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { contributorList } from 'src/__fixtures__/graphql/contributors';
import * as contributorQuery from 'src/apollo/queries/nr-contributors';
import { ContributorScheduleList } from 'src/components/contributor-schedule-list/contributor-schedule-list';
import { CONTRIBUTOR_SCHEDULE_HEADERS } from 'src/components/contributor-schedule-list/contributor-schedule-table';
import type { GetNRContributorsListQuery } from 'src/apollo/queries/nr-contributors/__generated__/get-nr-contributors';
import type { NrContributorsSearchQuery } from 'src/apollo/queries/nr-contributors/__generated__/nr-contributor-search';

describe('<ContributorScheduleList>', () => {
    let requestSpy: any;
    let searchRequestSpy: any;
    const searchResults = {
        nrContributorSearch: {
            contributors: [
                {
                    id: '1ec7c1bf-2318-4052-9406-a3e35a620bd3',
                    name: 'West, Brian',
                    abacusUnassignedContributionsCount: 1,
                    abacusSchedules: [
                        {
                            conditions: null,
                            scheduleId: '6',
                            scheduleName: 'something',
                            scheduleAttachments: { totalCount: 1 },
                        },
                    ],
                    __typename: 'NrContributor',
                },
            ],
            totalCount: 1,
        },
    };
    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        const getNRContributors = jest.fn().mockReturnValue(contributorList);
        requestSpy = jest
            .spyOn(contributorQuery, 'useNRContributorsList')
            .mockReturnValue({
                data: contributorList as GetNRContributorsListQuery,
                loading: false,
                error: undefined,
                getNRContributors: getNRContributors,
            });

        const getNRContributorSearchResult = jest
            .fn()
            .mockReturnValue(searchResults);
        searchRequestSpy = jest
            .spyOn(contributorQuery, 'useNRContributorSearch')
            .mockReturnValue({
                data: searchResults as NrContributorsSearchQuery,
                loading: false,
                error: undefined,
                getNRContributorSearchResult: getNRContributorSearchResult,
            });
    });

    const render = () => renderInAppContext(<ContributorScheduleList />);

    it('requests a list of contributors on render', () => {
        render();
        expect(requestSpy).toHaveBeenCalled();
    });

    it('renders a table with headers', () => {
        render();
        CONTRIBUTOR_SCHEDULE_HEADERS.forEach((header: any) =>
            expect(screen.getByText(header.title)).toBeDefined()
        );
    });

    it('renders a list of contributor schedules', () => {
        render();
        const bodyText: any = [];
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            'Abbott, Judith1ec7c1bf-2318-4052-9406-a3e35a620bd3',
            '25',
            'alt something - (2)Auto add newsomething - (3)',
            'Thomas Edward Yorke3be31516-bde0-4968-9fcf-421ebfc40a8f',
            '0',
            'something - (1)',
            'Zundel, Klaus63e4d0fd-51ae-417b-9aa1-fdb6a9c3bf9b',
            '21',
            '',
            'Haim, Este Arielle9ad6e907-ce55-4429-ba7e-70fb90391f8f',
            '21',
            '',
        ]);
    });

    it('renders filters', () => {
        render();
        expect(
            screen.getByPlaceholderText('Filter by Contributor Name or ID')
        ).toBeDefined();
        expect(
            screen.getByText('Show Unassigned Contributions Only')
        ).toBeDefined();
        expect(screen.queryByText('Clear Filters')).toBeNull();
    });

    it('on search, search request has been called', () => {
        render();
        const input = screen.getByTestId('searchFieldInput');
        fireEvent.change(input, { target: { value: 'Brian' } });
        expect(searchRequestSpy).toHaveBeenCalled();
    });

    it(`on click of "Show Unassigned Contributions Only" checkbox,
        search request has been called`, () => {
        render();
        const checkbox = screen.getByRole('checkbox');
        fireEvent.click(checkbox);
        expect(searchRequestSpy).toHaveBeenCalled();
    });
});
