import React from 'react';
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { renderInAppContext } from '@theorchard/suite-testing';
import * as trackSearchResponse from 'src/__fixtures__/graphql/track-search-response.json';
import * as contractTermQuery from 'src/apollo/queries/contract-term';
import * as trackQuery from 'src/apollo/queries/track-search';
import TrackSearchableSelect, {
    TrackSearchableSelectPropTypes,
} from 'src/components/shared/track-searchable-select';

describe('<TrackSearchableSelect/>', () => {
    const props: TrackSearchableSelectPropTypes = {
        onChange: jest.fn(),
        contractTermId: '1',
        tracksIsrcs: [],
        selectedTrackExceptionIsrcs: ['QMMZ200T0180'],
        labelIds: [1, 2],
        accountId: '1',
        setErrors: jest.fn(),
    };

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

    afterEach(jest.restoreAllMocks);

    let searchTracksMock: any;
    const getContractsTermsMock = jest.fn().mockReturnValue([]);

    beforeEach(() => {
        searchTracksMock = jest
            .spyOn(trackQuery, 'useTrackSearch')
            .mockReturnValue(
                async () =>
                    await Promise.resolve(
                        trackSearchResponse.globalSoundRecordingSearchES.items
                    )
            );

        jest.spyOn(
            contractTermQuery,
            'useContractTermsByAccount'
        ).mockReturnValue({
            data: { abacusContractTermsByAccount: [] },
            loading: false,
            getContractsTerms: getContractsTermsMock,
        });
    });

    it('renders', () => {
        render();
        expect(screen.getByText('Search for track(s)')).toBeDefined();
    });

    it('searches tracks on input change', async () => {
        render();
        const trackSelect = screen.getByRole('combobox');
        fireEvent.change(trackSelect, { target: { value: 'Test' } });
        await waitFor(() => {
            expect(screen.getByText('Test Track 1-QMMZ200T0180')).toBeDefined();
            expect(screen.getByText('Test Track 2-1118978765')).toBeDefined();
            expect(searchTracksMock).toHaveBeenCalled();
        });
    });

    it('on input blur, call useContractTermsByAccount', async () => {
        render();
        const trackSelect = screen.getByRole('combobox');
        fireEvent.change(trackSelect, { target: { value: 'Test' } });
        fireEvent.blur(trackSelect);
        await waitFor(() => {
            expect(getContractsTermsMock).not.toHaveBeenCalled();
        });
    });
});
