import React from 'react';
import { screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { contractPartyList } from 'src/__fixtures__/graphql/contract-party';
import * as storeList from 'src/__fixtures__/graphql/store-list-response.json';
import {
    transactionTypes,
    transactionTypeGroups,
} from 'src/__fixtures__/graphql/transaction-types';
import * as contractQuery from 'src/apollo/queries/contract';
import * as contractPartyQuery from 'src/apollo/queries/contract-party';
import * as storesQuery from 'src/apollo/queries/stores';
import * as transactionTypeQueries from 'src/apollo/queries/transaction-types';
import { noContributorTerms } from 'src/apollo/type-constants/contract';
import { NrContractTermsForm } from 'src/components/contract-terms-form-nr/nr-contract-terms-form';
import { CONTRACT_TYPES } from 'src/constants';
import { getContractDetail } from 'src/urls/frontend-royalties';
import type { GetStoresQuery } from 'src/apollo/queries/__generated__/stores';
import type { GetContractPartyListQuery } from 'src/apollo/queries/contract-party/__generated__/get-contract-party-list';

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

describe('<NrContractTermsForm>', () => {
    let useContractSpy: any;

    const contractMock = {
        abacusContract: {
            contractId: '123',
            contractType: CONTRACT_TYPES.NEIGHBOURING_RIGHTS,
            contractName: 'Test contract',
            account: {
                accountId: '123',
                accountName: 'test name',
                accountPaymentTerm: {
                    currencyCode: 'AUD',
                    accountPaymentTermId: '321',
                    paymentEntity: {
                        paymentEntityName: 'AWAL-UK',
                        referencePaymentEntityId: '1',
                    },
                },
                accountPayee: {
                    accountPayeeId: '123',
                    payoneerPayeeId: null,
                    payoneerPayeeName: null,
                },
            },
        },
    };

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

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        jest.spyOn(
            contractPartyQuery,
            'useContractPartyListLazyQuery'
        ).mockReturnValue({
            data: contractPartyList as GetContractPartyListQuery,
            error: undefined,
            loading: false,
            getAbacusContractPartyList: jest
                .fn()
                .mockReturnValue(contractPartyList),
        });
        jest.spyOn(
            transactionTypeQueries,
            'useTransactionTypes'
        ).mockReturnValue({ data: transactionTypes, loading: false });
        jest.spyOn(
            transactionTypeQueries,
            'useTransactionTypeGroups'
        ).mockReturnValue({ data: transactionTypeGroups, loading: false });
        jest.spyOn(storesQuery, 'useStoreList').mockReturnValue({
            data: storeList as GetStoresQuery,
            loading: false,
        });

        useContractSpy = jest
            .spyOn(contractQuery, 'useContractById')
            .mockReturnValue({
                data: contractMock,
                error: undefined,
                loading: false,
            });
    });

    it('renders <NrContractTermsForm>', () => {
        render();

        expect(screen.getByText('Add Term')).toBeDefined();
        expect(useContractSpy).toHaveBeenCalled();
    });

    it('renders <NrContractTermsForm> fields', () => {
        render();

        expect(screen.getByText('Term Name')).toBeDefined();
        expect(screen.getByText('Term Type')).toBeDefined();
        expect(screen.queryByText('Contributor')).toBeNull();
        expect(screen.queryByText('Schedules')).toBeNull();
    });

    it('redirects to contract detail page when cancel button is clicked', () => {
        render();
        const cancelButton = screen.getAllByRole('link');
        expect(cancelButton[0].getAttribute('href')).toEqual(
            getContractDetail(123)
        );
    });

    it('shows a message when contract is not a NR contract', () => {
        jest.spyOn(contractQuery, 'useContractById').mockReturnValue({
            data: {
                abacusContract: {
                    ...contractMock.abacusContract,
                    contractType: CONTRACT_TYPES.DISTRIBUTION,
                },
            },
            error: undefined,
            loading: false,
        });
        render();
        expect(
            screen.getByText(noContributorTerms(CONTRACT_TYPES.DISTRIBUTION))
        ).toBeDefined();
    });
});
