import React from 'react';
import { screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import { contractPartyList } from 'src/__fixtures__/graphql/contract-party';
import * as contractPartyQuery from 'src/apollo/queries/contract-party';
import { NO_NR_CONTRIBUTORS_TEXT } from 'src/apollo/type-constants/contract';
import {
    NrContractContributorsList,
    NrContractContributorsListProps,
} from 'src/components/contract-detail/nr-contract-contributors-list';
import { ABACUS_PROFILE } from 'src/constants';
import { editContractContributors } from 'src/urls/frontend-royalties';

jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useParams: jest.fn().mockReturnValue({ contractId: 123 }),
}));

describe('<NrContractContributorsList/>', () => {
    let useContractPartyListSpy: any;
    const props: NrContractContributorsListProps = {
        nrContractContributorsTotal: 10,
        setNrContractContributorsTotal: jest.fn(),
    };
    const identity = createIdentity({ profileType: ABACUS_PROFILE });
    const render = () =>
        renderInAppContext(<NrContractContributorsList {...props} />, {
            identity,
        });

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        useContractPartyListSpy = jest
            .spyOn(contractPartyQuery, 'useContractPartyList')
            .mockReturnValue({
                data: contractPartyList,
                loading: false,
                error: undefined,
            });
    });

    it('renders', () => {
        render();
        expect(screen.getAllByText('Contributors')).toBeDefined();
        expect(useContractPartyListSpy).toHaveBeenCalled();
    });

    it('renders Edit button', () => {
        render();
        const editButtons = screen.getAllByRole('link');
        expect(editButtons[0]).toHaveAttribute(
            'href',
            editContractContributors(123)
        );
    });

    it('renders table columns', () => {
        render();
        expect(screen.getAllByText('Contributors')).toBeDefined();
        expect(
            screen.getByText('Schedules (# Of Contributions)')
        ).toBeDefined();
    });

    it('shows a message when no contributors have been added', () => {
        jest.spyOn(contractPartyQuery, 'useContractPartyList').mockReturnValue({
            data: {
                abacusContractParties: {
                    __typename: 'AbacusContractPartyResult',
                    totalCount: 0,
                    items: [],
                },
            },
            loading: false,
            error: undefined,
        });
        render();
        expect(screen.getByText(NO_NR_CONTRIBUTORS_TEXT)).toBeDefined();
    });

    it('renders Add button when no contributors have been added', () => {
        jest.spyOn(contractPartyQuery, 'useContractPartyList').mockReturnValue({
            data: {
                abacusContractParties: {
                    __typename: 'AbacusContractPartyResult',
                    totalCount: 0,
                    items: [],
                },
            },
            loading: false,
            error: undefined,
        });

        render();
        const addButton = screen.getByRole('link', { name: '+ Add' });
        expect(addButton).toHaveAttribute(
            'href',
            editContractContributors(123)
        );
    });

    it('renders a list of contract contributors', () => {
        render();
        const bodyText: any = [];
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            'Thomas Edward Yorke3be31516-bde0-4968-9fcf-421ebfc40a8f',
            'Test Schedule - (1)',
            'Bell, Robert E582f9577-73cb-4885-b8eb-c2ce70ac9ecb',
            'Test Schedule 2 - (1)',
            'Test Schedule 3 - (2)Auto add new',
        ]);
    });

    it('renders links to contributor detail page', () => {
        const contractContributors: any =
            contractPartyList.abacusContractParties.items;
        render();
        const links = screen.getAllByRole('link');
        expect(links[1].getAttribute('href')).toContain(
            `/contributor/${contractContributors[0]['contractPartyObject']['id']}`
        );
        expect(links[2].getAttribute('href')).toContain(
            `/contributor/${contractContributors[1]['contractPartyObject']['id']}`
        );
    });
});
