import React from 'react';
import { screen, waitFor } from '@testing-library/react';
import { Segment } from '@theorchard/suite-frontend';
import { renderInAppContext } from '@theorchard/suite-testing';
import { waitForLoaded, userEvent } from 'lib/test/helpers';
import * as labelParticipantSearch from 'src/data/queries/labelParticipantSearch/labelParticipantSearch';
import * as orchardLabels from 'src/data/queries/orchardLabels/orchardLabels';
import * as trackProductOwsSearch from 'src/data/queries/owsSearch/owsSearch';
import {
    labelParticipantSearchResult,
    trackProductOwsSearchResult,
    orchardLabelsMock,
} from '../mocks';
import SelectExistingSong from '../selectExistingSong';

describe('<SelectExistingSong>', () => {
    const renderComponent = (contextProps: Object) =>
        renderInAppContext(<SelectExistingSong />, contextProps);

    const mockOwsSearch = () => {
        jest.spyOn(trackProductOwsSearch, 'useLazyOwsSearch').mockReturnValue([
            jest.fn(),
            trackProductOwsSearchResult,
        ]);
    };

    const mockParticipants = () => {
        jest.spyOn(
            labelParticipantSearch,
            'useLazyLabelParticipantSearch'
        ).mockReturnValue([jest.fn(), labelParticipantSearchResult]);
    };

    beforeEach(() => {
        jest.spyOn(Segment, 'trackEvent');
        jest.spyOn(orchardLabels, 'useOrchardLabels').mockReturnValue({
            loading: false,
            error: undefined,
            data: orchardLabelsMock,
        });
    });

    afterEach(() => {
        jest.restoreAllMocks();
    });

    it('has zero state', async () => {
        jest.spyOn(
            labelParticipantSearch,
            'useLazyLabelParticipantSearch'
        ).mockReturnValue([
            jest.fn(),
            {
                loading: false,
                called: true,
                participants: [],
                error: undefined,
            },
        ]);

        jest.spyOn(trackProductOwsSearch, 'useLazyOwsSearch').mockReturnValue([
            jest.fn(),
            {
                loading: false,
                called: true,
                products: [],
                songs: [],
                error: undefined,
            },
        ]);

        renderComponent({});
        await waitForLoaded();

        expect(screen.getByText('There are no results')).toBeTruthy();
    });

    it('can search', async () => {
        mockParticipants();
        mockOwsSearch();
        renderComponent({});
        await waitForLoaded();

        await userEvent.type(
            screen.getByPlaceholderText('Search for a track...'),
            'Cow'
        );

        await waitFor(() => {
            expect(screen.queryByText('There are no results')).toBeFalsy();
        });

        expect(screen.getAllByText('Giving You My Love')).toHaveLength(2);
        expect(screen.getAllByText('Artisan Pier')).toHaveLength(1);
        expect(screen.getAllByText('Edgar Terry')).toHaveLength(1);

        expect(screen.getAllByText('Love Kills')).toHaveLength(3);
        expect(screen.getAllByText('Robin Auld')).toHaveLength(4);
        expect(screen.getAllByText('196292480290')).toHaveLength(2);

        expect(screen.getAllByText('Love')).toHaveLength(1);
        expect(screen.getAllByText('Stormtroopers of Love')).toHaveLength(1);
        expect(
            screen.getAllByText(
                'Bjørn Bue Houmand, Kasper Wedel Jensen, ' +
                    'Allan Damm, Jens Peter Bjørn Hansen, Morten Harder Kragelund'
            )
        ).toHaveLength(1);
        expect(screen.getAllByText('196626147592')).toHaveLength(1);
        expect(screen.getAllByText('Go Go Graveyard!')).toHaveLength(1);

        expect(screen.getAllByText('Lucinda Williams')).toHaveLength(1);
        expect(screen.getAllByText('You Wreck Me')).toHaveLength(1);
        expect(screen.getAllByText('Tom Petty, Mike Campbell')).toHaveLength(1);
        expect(
            screen.getAllByText("Runnin' Down a Dream: A Tribute to Tom Petty")
        ).toHaveLength(1);
        expect(screen.getAllByText('404606')).toHaveLength(1);
    });
});
