import '@testing-library/jest-dom/extend-expect';
import React, { FC } from 'react';
import { formatMessage } from '@orchard/frontend-localization';
import renderWithProvider from 'lib/testing/provider';
import { mockQuery } from 'lib/testing/mocks';
import { ComparisonFilter, ComparisonSongs } from 'src/definitions';
import { TERM_HEADER } from 'src/components/performanceOverTime/PerformanceOverTime';
import CompareSection, { Props } from '../CompareSection';

describe('<CompareSection>', () => {
    const headerText = 'HeaderTitle';
    const defaultProps: Props = { headerText, Content: () => <div> </div> };

    const renderMocked = async (props: Partial<Props> = {}, data: Partial<ComparisonFilter> = {}) => {
        const { selectedSongIds = [] } = data;

        const container = await renderWithProvider(() => <CompareSection {...defaultProps} {...props} />, {
            filter: { selectedSongIds },
            mocks: selectedSongIds.map(isrc =>
                mockQuery('SoundRecordingMetadataQuery', {
                    variables: { isrc }
                }))
        });

        return container;
    };

    test('shows header if empty if POT component header text seen', async () => {
        const potHeader = formatMessage(TERM_HEADER);
        const potProps: Props = { headerText: potHeader, Content: () => <div> </div> };
        const container = await renderMocked(potProps);
        const needle = container.getByText(potHeader);
        expect(needle).toBeVisible();
    });

    test('does not show header title without songIds', async () => {
        const container = await renderMocked();

        const headerTitle = container.queryByText(headerText);
        expect(headerTitle).toBeNull();
    });

    test('does not show header component without songIds', async () => {
        const contentText = 'CONTENT';
        const HeaderMenu = () => <div>{contentText}</div>;

        const container = await renderMocked({ HeaderMenu });

        const component = container.queryByText(contentText);
        expect(component).toBeNull();
    });

    describe('songs selected', () => {
        const contentText = 'SONG';
        const Content: FC<ComparisonSongs> = ({ songs }) => (
            <div>
                {songs.map(({ id }) => (
                    <div key={id}>
                        {contentText}
                        {id}
                    </div>
                ))}
            </div>
        );

        test('shows content component', async () => {
            const selectedSongIds = ['CODE1', 'CODE2'];
            const container = await renderMocked({ Content }, { selectedSongIds });
            selectedSongIds.forEach(id => {
                const component = container.getByText(`${contentText}${id}`);
                expect(component).toBeVisible();
            });
        });
    });

    describe('no songs selected', () => {
        const emptyText = 'EMPTY';
        const EmptyState = () => <div>{emptyText}</div>;

        test('component does not show', async () => {
            const container = await renderMocked({ EmptyState });
            const component = await container.queryByText(emptyText);
            expect(component).toBeNull();
        });
    });
});
