import React from 'react';
import { fireEvent } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import { DropdownOption } from 'src/components/dropdown';
import SearchableDropdown, { CLASSNAME } from '../searchableDropdown';
import { SearchableDropdownProps } from '../types';

describe('<SearchableDropdown>', () => {
    const optionOne: DropdownOption = {
        label: 'Label One', value: 'label1',
    };
    const optionTwo: DropdownOption = {
        label: 'Label Two', value: 'label2',
    };
    const defaultProps: SearchableDropdownProps = {
        name: 'Test Name',
        onInputChange: jest.fn(),
        onChange: jest.fn(),
        options: [optionOne, optionTwo]
    };

    const render = (props?: Partial<SearchableDropdownProps>) =>
        renderInAppContext(<SearchableDropdown {...defaultProps} {...props} />);

    test('renders default component', () => {
        const className = 'TestClass';
        const { container } = render({ className });

        expect(container.querySelector(`.${CLASSNAME}`)).toBeVisible();
    });

    test('renders clear icon', () => {
        const { container } = render({ selectedOption: optionOne, clearable: () => true });

        expect(container.querySelector('.Clear')).toBeVisible();
    });

    test('renders formatted option', () => {
        const testId = 'TestId';
        const { getByText } = render({
            selectedOption: optionOne,
            formatOptionLabel: (option, { context }) => (
                <div>
                    <div data-testid={testId}>
                        {option.label}
                    </div>
                    <div>CONTEXT:{context}</div>
                </div>
            )
        });

        expect(getByText(optionOne.label)).toBeVisible();
        expect(getByText('CONTEXT:value')).toBeVisible();
    });

    test('shows loading state when loading and search term', async () => {
        const { container, findByText } = render({ loading: true, options: [], hideIfEmpty: false });
        const input = container.getElementsByTagName('input').item(0);
        if (input) {
            fireEvent.mouseDown(input);
            fireEvent.change(input, { target: { value: 'searching' } });
        }

        const loadingMessage = await findByText('Loading...');

        expect(loadingMessage).toBeVisible();
    });

    test('does not show loading state when loading but no search term', () => {
        const { container, queryByText } = render({ loading: true, options: [], hideIfEmpty: false });
        const input = container.getElementsByTagName('input').item(0);
        if (input)
            fireEvent.mouseDown(input);
        expect(queryByText('Loading...')).toBeNull();
    });
});
