import React from 'react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as runControllers from 'src/__fixtures__/graphql/contract-run-controller-list-response.json';
import { mockUseRunControllerList } from 'src/__fixtures__/graphql/run-controller-list-hooks';
import * as runControllerQuery from 'src/apollo/queries/run-controller';
import {
    RunControllerSelect,
    RunControllerSelectPropTypes,
} from 'src/components/contract-lifecycle-shared/run-controller-select';
import type { GetRunControllersQuery } from 'src/apollo/queries/__generated__/run-controller';

describe('<RunControllerSelect> layout', () => {
    const render = (props: RunControllerSelectPropTypes) =>
        renderInAppContext(<RunControllerSelect {...props} />);

    const props: any = {
        accountId: '405',
        contractType: 'distribution',
        onChange: jest.fn(),
        disabled: false,
        value: '',
    };

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        mockUseRunControllerList();
    });

    it('renders expected markup', () => {
        const { container } = render(props);
        expect(container).toBeDefined();
        expect(screen.getByText('Choose...')).toBeDefined();
    });

    it('when there are no search results for search keyword', async () => {
        render(props);
        fireEvent.change(screen.getByRole('combobox'), {
            target: { value: 'label' },
        });
        const noResults = await screen.findByText('No options');
        expect(noResults).toBeDefined();
    });

    it('renders selected run controller', async () => {
        const newProps = { ...props, value: '2722' };
        render(newProps);
        const selectedRunController =
            await screen.findByText('Test Priority One');
        expect(selectedRunController).toBeDefined();
    });

    it('when there are search results for search keyword', async () => {
        const { container } = render(props);
        fireEvent.change(screen.getByRole('combobox'), {
            target: { value: 'Test' },
        });
        await waitFor(() => {
            expect(container.querySelectorAll('.Select__option').length).toBe(
                2
            );
        });
    });

    it('when there are more than 100 run controllers', async () => {
        const mockRunControllers = { ...runControllers };
        mockRunControllers.abacusRunControllers.totalCount = 140;
        const queryMock = jest.spyOn(
            runControllerQuery,
            'useRunControllerList'
        );
        queryMock.mockReturnValue({
            data: mockRunControllers as GetRunControllersQuery,
            loading: false,
            refetch: jest.fn().mockReturnValue(mockRunControllers),
        });
        render(props);
        await waitFor(() => {
            expect(queryMock).toHaveBeenCalledTimes(2);
            expect(queryMock).toHaveBeenNthCalledWith(1, {
                limit: 100,
                offset: 0,
                contractType: props.contractType,
                accountId: props.accountId,
            });
            expect(queryMock).toHaveBeenNthCalledWith(2, {
                limit: 140,
                offset: 0,
                contractType: props.contractType,
                accountId: props.accountId,
            });
        });
    });
});
