import React from 'react';
import { screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import {
    contractAdvancesPaidList,
    contractAdvancesPaidListWithNullValues,
} from 'src/__fixtures__/graphql/contract-advances';
import { AbacusContractAdvanceMilestone } from 'src/apollo/definitions/globalTypes';
import ContractAdvancePaidList, {
    ContractAdvancePaidListProps,
} from 'src/components/contract-advance-list/contract-advance-paid-list';
import ContractAdvancePaidListTableColumns from 'src/components/contract-advance-list/contract-advance-paid-list-table-columns';
import { ABACUS_PROFILE, NO_PAID_ADVANCES, USER_FEATURES } from 'src/constants';
import { getAdvancePaymentDetail } from 'src/urls/frontend-royalties';

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

describe('<ContractAdvancePaidList>', () => {
    const defaultProps = {
        paidAdvances:
            contractAdvancesPaidList as ContractAdvancePaidListProps['paidAdvances'],
        paidAdvancesLoading: false,
        paidAdvancesRequestParams: {
            contractId: '123',
            limit: 10,
            offset: 0,
        },
        setPaidAdvancesRequestParams: jest.fn(),
    };

    const mockFeatures = {
        [USER_FEATURES.ABACUS_CONTRACT_ADVANCE_MILESTONE_NEW_OPTIONS]: false,
    };

    const render = (
        props: ContractAdvancePaidListProps,
        features: { [x: number]: boolean } = mockFeatures
    ) =>
        renderInAppContext(<ContractAdvancePaidList {...props} />, {
            identity: createIdentity({
                features,
                profileType: ABACUS_PROFILE,
                id: 'Jane User',
            }),
        });

    it('show message when there are no paid advances', () => {
        const updatedProps = {
            ...defaultProps,
            paidAdvances: {
                abacusContractAdvancesPaid: { items: [], totalCount: 0 },
            },
        };
        render(updatedProps);

        expect(screen.getByText(NO_PAID_ADVANCES)).toBeDefined();
        expect(screen.getByTestId('EmptyStateIllustration')).toBeDefined();
    });

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

    it('renders a list of paid advances', () => {
        render(defaultProps);
        const bodyText: any = [];
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            '2022-09-01',
            'Test Advance Description',
            '100.00',
            'GBP (Pound Sterling)',
            '-33',
            '123',
            '100%',
            '2',
            'Recoupment',
            'Test Milestone Description',
            '2022-09-16',
            'Paid via check',
            '2022-09-30',
            'June 2022',
            'USD (US Dollar)',
            '101.00',
        ]);

        const links = screen.getAllByRole('link');
        expect(links[0].textContent).toEqual('Test Advance Description');
        expect(links[0].getAttribute('href')).toContain(
            getAdvancePaymentDetail('12')
        );
    });

    it('renders a list of paid advances with null values', () => {
        render({
            ...defaultProps,
            paidAdvances:
                contractAdvancesPaidListWithNullValues as ContractAdvancePaidListProps['paidAdvances'],
        });
        const bodyText: any = [];
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            '2022-09-01',
            'Test Advance Description',
            '100.00',
            'GBP (Pound Sterling)',
            '-33',
            '123',
            '100%',
            '2',
            'Recoupment',
            'Test Milestone Description',
            '2022-09-16',
            'Paid via check',
            '-',
            'June 2022',
            '-',
            '-',
        ]);

        const links = screen.getAllByRole('link');
        expect(links[0].textContent).toEqual('Test Advance Description');
        expect(links[0].getAttribute('href')).toContain(
            getAdvancePaymentDetail('12')
        );
    });

    it('renders a list of paid advances when ff is enabled', () => {
        const props = {
            paidAdvances: {
                abacusContractAdvancesPaid: {
                    items: [
                        {
                            ...contractAdvancesPaidList
                                .abacusContractAdvancesPaid.items[0],
                            milestone:
                                AbacusContractAdvanceMilestone.fund_non_contingent,
                        },
                    ],
                    totalCount: 1,
                },
            },
            paidAdvancesLoading: false,
            paidAdvancesRequestParams: {
                contractId: '123',
                limit: 10,
                offset: 0,
            },
            setPaidAdvancesRequestParams: jest.fn(),
        };
        const updatedMockFeatures = {
            [USER_FEATURES.ABACUS_CONTRACT_ADVANCE_MILESTONE_NEW_OPTIONS]: true,
        };
        render(props, updatedMockFeatures);
        const bodyText: any = [];
        document
            .querySelectorAll('div.GridTable-cell')
            .forEach((body: any) => bodyText.push(body.textContent));
        expect(bodyText).toEqual([
            '2022-09-01',
            'Test Advance Description',
            '100.00',
            'GBP (Pound Sterling)',
            '-33',
            '123',
            '100%',
            '2',
            'Fund - Non-Contingent',
            'Test Milestone Description',
            '2022-09-16',
            'Paid via check',
            '2022-09-30',
            'June 2022',
            'USD (US Dollar)',
            '101.00',
        ]);

        const links = screen.getAllByRole('link');
        expect(links[0].textContent).toEqual('Test Advance Description');
        expect(links[0].getAttribute('href')).toContain(
            getAdvancePaymentDetail('12')
        );
    });
});
