import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as contractQuery from 'src/apollo/queries/contract';
import useContractSearch, {
    ContractSearchPropType,
} from 'src/hooks/contract-search';

describe('useContractSearch hook', () => {
    const className = 'mock-contract-search-hook';
    const mockContractResult = {
        abacusContracts: {
            totalCount: 12,
            items: [
                {
                    account: null,
                    contractId: '2',
                    contractName: 'Test 2',
                    contractType: 'distribution',
                },
            ],
        },
    };
    let renderContractSearch;

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        jest.spyOn(contractQuery, 'useContractSearchQuery').mockReturnValue(
            async () =>
                await Promise.resolve(
                    mockContractResult?.abacusContracts?.items
                )
        );
    });

    const MockComponent = (props: ContractSearchPropType) => {
        ({ renderContractSearch } = useContractSearch({ ...props, className }));
        return <span>{renderContractSearch()}</span>;
    };

    const render = (props: ContractSearchPropType = { contractType: null }) =>
        renderInAppContext(<MockComponent {...props} />);

    it('renders a searchable select list of contracts', () => {
        render();
        expect(screen.getByText('Search for contract')).toBeDefined();
    });

    it('searches contracts', async () => {
        render();
        const contractSearchSelect = screen.getByRole('combobox');

        fireEvent.change(contractSearchSelect, { target: { value: 'Test' } });
        fireEvent.keyPress(contractSearchSelect, {
            key: 'Enter',
            keyCode: 13,
            which: 13,
        });

        const contractName = await screen.findByText('Test 2 - 2');
        expect(contractName).toBeDefined();
    });

    it('preselects contract by ID', async () => {
        mockContractResult.abacusContracts.items.push(
            {
                account: null,
                contractId: '3',
                contractName: 'Test 3',
                contractType: 'distribution',
            },
            {
                account: null,
                contractId: '4',
                contractName: 'Test 4',
                contractType: 'distribution',
            }
        );
        render({ contractType: null, contractIdPreselected: '3' });

        const contractName = await screen.findByText('Test 3 - 3');
        expect(contractName).toBeDefined();
    });
});
