import React from 'react';
import { ApolloError } from '@apollo/client';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { contractAdvancesQualifiedList } from 'src/__fixtures__/graphql/contract-advances';
import * as contractAdvanceQuery from 'src/apollo/queries/contract-advance';
import ContractAdvancesQualifiedSelect, {
    ContractAdvancesQualifiedSelectPropTypes,
} from 'src/components/payment-group-form/contract-advances-qualified-select';
import { NO_PENDING_ADVANCES } from 'src/constants';
import type { GetContractAdvancesQualifiedQuery } from 'src/apollo/queries/contract-advance/__generated__/get-contract-advances-qualified-list';

interface ContractAdvanceSpyInstance {
    data: GetContractAdvancesQualifiedQuery | undefined;
    error: ApolloError | undefined;
    loading: boolean;
}

describe('<ContractAdvancesQualifiedSelect>', () => {
    const defaultProps: ContractAdvancesQualifiedSelectPropTypes = {
        contractId: '537382',
        changeHandler: jest.fn(),
        setPaymentNameHandler: jest.fn(),
        contractAdvanceId: '537382',
        referencePaymentTypeId: '1',
    };

    const render = () =>
        renderInAppContext(
            <ContractAdvancesQualifiedSelect {...defaultProps} />
        );

    let requestSpy: jest.SpyInstance<ContractAdvanceSpyInstance>;

    beforeEach(() => {
        requestSpy = jest
            .spyOn(contractAdvanceQuery, 'useContractAdvancesQualified')
            .mockReturnValue({
                data: contractAdvancesQualifiedList as GetContractAdvancesQualifiedQuery,
                loading: false,
                error: undefined,
            });
    });

    afterEach(jest.restoreAllMocks);

    it('renders', () => {
        render();
        expect(screen.getByText('Select')).toBeDefined();
        expect(
            screen.getByTestId('Dropdown_ContractAdvancePendingDropdown')
        ).toBeDefined();
    });

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

    it('renders pending advance list when select is clicked', () => {
        render();

        const contractAdvancePendingDropdown = screen.getByText('Select');

        if (contractAdvancePendingDropdown) {
            fireEvent.focus(contractAdvancePendingDropdown);
            fireEvent.keyDown(contractAdvancePendingDropdown, {
                key: 'ArrowDown',
                code: 40,
            });
        }
        expect(screen.getByText('Test Advance | $1,289.89')).toBeDefined();
        expect(
            screen.getByText('Advance Description Payment | $78,921.98')
        ).toBeDefined();
        expect(
            screen.getByText('Test Advance 3 | $789,657,896.00')
        ).toBeDefined();
    });

    it('disables dropdown when there are no items in the list', () => {
        requestSpy.mockReturnValue({
            data: {
                abacusContractAdvancesQualified: { items: [], totalCount: 0 },
            },
            loading: false,
            error: undefined,
        });
        const { container } = render();

        expect(
            container.getElementsByClassName('Select__control--is-disabled')
                .length
        ).toBe(1);
        expect(screen.getByText(NO_PENDING_ADVANCES)).toBeDefined();
    });
});
