import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { waitForElement } from '@testing-library/react';
import { flatten } from 'lodash';

import renderWithProvider from 'lib/testing/provider';
import SoundRecordingStreamsBreakdownQuery from 'src/queries/soundRecordingStreamsBreakdown.gql';
import { SoundRecordingStreamsBreakdown } from 'src/definitions';
import { CLASSNAME_CONTENT } from 'src/components/compareSection';
import { HIGHWATER_MARK, PAST28 } from 'src/constants/periods';

import { createSoundRecordingStreamsBreakdown } from 'lib/factories/soundRecording';

import { TERM_TRIGGER_LABEL as DATASOURCES_TERM_TRIGGER } from '../../sourcesStatus/SourcesStatus';
import { TEST_ID as CHART_TEST_ID } from '../chart/Chart';

import SourceOfStreams, {
    Content, TERM_HEADER
} from '../SourceOfStreams';

describe('<SourceOfStreams>', () => {
    test('Does not show header if no data', async () => {
        const container = await renderWithProvider(SourceOfStreams);

        const headerTitle = container.queryByText(TERM_HEADER);
        expect(headerTitle).toBeNull();

    });

    test('does not show content by default', async () => {
        const { container } = await renderWithProvider(SourceOfStreams);

        const content = container.getElementsByClassName(CLASSNAME_CONTENT).item(0);
        expect(content).toBeNull();
    });
});

describe('Content', () => {
    const ISRC1 = 'ISRCCODE1';
    const ISRC2 = 'ISRCCODE2';

    const sourceValue = (value: number) => ({ value, total: 0, growthPercentage: null });

    const records: Record<string, SoundRecordingStreamsBreakdown> = {
        [ISRC1]: createSoundRecordingStreamsBreakdown({
            active: sourceValue(1),
            passive: sourceValue(11),
            collection: sourceValue(111),
            sources: []
        }),
        [ISRC2]: createSoundRecordingStreamsBreakdown({
            active: sourceValue(2),
            passive: sourceValue(22),
            collection: sourceValue(222),
            sources: []
        })
    };

    const renderMocked = async (
        ids: string[], potMetric: string = 'streams', countries: string[] = [], stores: number[] = [], datePeriod: string = PAST28
    ) => {
        const mocks = flatten(ids.map(isrc => ([{
            request: {
                query: SoundRecordingStreamsBreakdownQuery,
                variables: { isrc, countries, startDate: HIGHWATER_MARK, days: -28 }
            },
            result: {
                data: records[isrc]
            }
        }])));

        return renderWithProvider(() => (
            <Content
                selectedSongIds={ids}
                potMetric={potMetric}
                countryFilter={countries}
                storeFilter={stores}
                dateFilter={datePeriod}
                songs={[]}
            />
        ), { mocks });
    };

    describe('is loaded', () => {
        test('renders performance chart', async () => {
            const ids = [ISRC1, ISRC2];
            const container = await renderMocked(ids);

            const chart = await waitForElement(() =>
                container.getByTestId(CHART_TEST_ID));

            expect(chart).toBeVisible();
        });

        test('shows sources', async () => {
            const ids = [ISRC1, ISRC2];
            const container = await renderMocked(ids);

            const sourcePopoverTrigger = container.getByText(DATASOURCES_TERM_TRIGGER);
            expect(sourcePopoverTrigger).toBeVisible();
        });
    });
});
