import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { accountList } from 'src/__fixtures__/graphql/account-list';
import * as accountQuery from 'src/apollo/queries/account';
import useAccountSearch, {
    AccountSearchPropType,
} from 'src/hooks/account-search';
import type { GetAccountsListQuery } from 'src/apollo/queries/account/__generated__/get-accounts-list';

describe('useAccountSearch hook', () => {
    const className = 'mock-account-search-hook';
    const mockAccountResult = accountList;

    let renderAccountSearch: any;

    afterEach(jest.restoreAllMocks);

    beforeEach(() => {
        jest.spyOn(accountQuery, 'useAccountSearchQuery').mockReturnValue(
            async () =>
                await Promise.resolve(
                    mockAccountResult.abacusAccounts
                        .items as GetAccountsListQuery['abacusAccounts']['items']
                )
        );
    });

    const MockComponent = (props: AccountSearchPropType) => {
        ({ renderAccountSearch } = useAccountSearch({ ...props, className }));
        return <span>{renderAccountSearch()}</span>;
    };

    const render = (props = {}) =>
        renderInAppContext(<MockComponent {...props} />);

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

    it('returns the selected account', () => {
        const props = {
            selectedOption: { label: 'Test Account', value: '1033113' },
        };
        render(props);
        expect(screen.getByText('Test Account')).toBeDefined();
    });

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

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

        const accountName = await screen.findByText('Test Account 1 - 1');
        expect(accountName).toBeDefined();
    });

    it('renders the selected account in search dropdown', async () => {
        const props = {
            selectedOption: 2,
            accountSearchResults: [
                {
                    label: 'Test Account 2',
                    value: 2,
                },
            ],
        };
        render(props);

        const accountSearchSelect = screen.getByRole('combobox');

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

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