import React from 'react';
import { screen } from '@testing-library/react';
import { createIdentity, renderInAppContext } from '@theorchard/suite-testing';
import { contractDetails as mockContract } from 'src/__fixtures__/graphql/contract-details';
import {
    NrContractTermDetail,
    NrContractTermDetailPropType,
} from 'src/components/contract-detail/nr-contract-term-detail';
import { ABACUS_PROFILE, CONTRACT_TERM_TYPES } from 'src/constants';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import { initialTermsState } from 'src/reducers/contract-term/contract-terms-details-reducer';

const componentInContext = (
    contextValues: any,
    props: NrContractTermDetailPropType
) => (
    <ContractTermContext.Provider value={contextValues}>
        <NrContractTermDetail {...props} />
    </ContractTermContext.Provider>
);

describe('<NrContractTermDetail>', () => {
    const identity = createIdentity({ profileType: ABACUS_PROFILE });
    const term = mockContract.abacusContract.contractTerms.filter(
        term =>
            term.termType === CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE ||
            term.termType === CONTRACT_TERM_TYPES.CONTRIBUTION_SCHEDULE
    )[0] as NrContractTermDetailPropType['term'];
    const render = (contextValues: any, props: NrContractTermDetailPropType) =>
        renderInAppContext(componentInContext(contextValues, props), {
            identity,
        });
    const contextValues = { state: initialTermsState, dispatch: jest.fn() };
    const props = { term };

    describe('renders terms correctly', () => {
        it('renders header', () => {
            render(contextValues, props);
            const block = screen.getByTestId('NRTermsBlock');
            expect(block.querySelector('.header')).toHaveTextContent(
                `${term.contractTermName} (${term.contractTermId})EditContributor Only`
            );
        });

        it('renders table for contributors', () => {
            const term = mockContract.abacusContract.contractTerms.filter(
                term =>
                    term.termType === CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE
            )[0] as NrContractTermDetailPropType['term'];
            const propsContributor = {
                ...props,
                term,
            };
            render(contextValues, propsContributor);
            expect(props.term.termType).toEqual(
                CONTRACT_TERM_TYPES.CONTRIBUTOR_SCHEDULE
            );
            expect(screen.getByTestId('NRTermsTable')).toBeDefined();
            expect(screen.getByText('Contributors')).toBeDefined();
            expect(screen.getByText('Term Condition Name')).toBeDefined();
            expect(screen.getByText('Transaction type')).toBeDefined();
            expect(screen.getByText('Service')).toBeDefined();
            expect(screen.getByText('Country')).toBeDefined();
            expect(screen.getByText('Commission')).toBeDefined();
            expect(screen.getByText('Test contributor name')).toBeDefined();
            expect(
                screen.getAllByTestId('NRTermsTableConditionRow').length
            ).toEqual(props?.term?.conditions?.length);
        });

        it('renders table for schedules', () => {
            const term = mockContract.abacusContract.contractTerms.filter(
                term =>
                    term.termType === CONTRACT_TERM_TYPES.CONTRIBUTION_SCHEDULE
            )[0] as NrContractTermDetailPropType['term'];
            const propsSchedule = {
                ...props,
                term,
            };
            render(contextValues, propsSchedule);
            expect(screen.getByTestId('NRTermsTable')).toBeDefined();
            expect(screen.getByText('Schedule')).toBeDefined();
            expect(screen.getByText('Term Condition Name')).toBeDefined();
            expect(screen.getByText('Transaction type')).toBeDefined();
            expect(screen.getByText('Service')).toBeDefined();
            expect(screen.getByText('Country')).toBeDefined();
            expect(screen.getByText('Commission')).toBeDefined();
            expect(screen.getByText('Test schedule name (1)')).toBeDefined();
            expect(
                screen.getAllByTestId('NRTermsTableConditionRow').length
            ).toEqual(props?.term?.conditions?.length);
        });
    });
});
