import executeHook from 'lib/testing/hooks';
import { mockQuery } from 'lib/testing/mocks';
import { PAST28, HIGHWATER_MARK } from 'src/constants/periods';
import { selectCountryStreamsRecords, TopCountry } from 'src/selectors';
import { STORE_SPOTIFY } from 'src/constants/stores';
import { DOWNLOADS } from 'src/constants/graphs';
import { ComparisonSong } from 'src/definitions';
import {
    createSoundRecordingMetadata,
    createSoundRecordingCountryStreams
} from 'lib/factories/soundRecording';
import {
    useBatchCountriesQuery
} from '..';

const CODE1 = 'CODE1';
const CODE2 = 'CODE2';
const selectedSongIds = [CODE1, CODE2];
const selectedStoreIds = [STORE_SPOTIFY];

describe('useBatchCountriesQuery', () => {
    test('returns empty data', async () => {
        const expectedResult = {
            loading: false,
            data: [],
            count: 5,
        };

        const result = await executeHook(useBatchCountriesQuery, {
            arguments: {},
            waitUntilMatch: expectedResult
        });

        expect(result).toEqual(expectedResult);
    });

    describe('with downloads', () => {
        test('returns countries downloads data for each song', async () => {
            const song: ComparisonSong = ({
                id: CODE1,
                loading: false,
                error: false,
                data: createSoundRecordingMetadata({ isrc: CODE1 }).soundRecording || undefined,
            });
            const result = await executeHook(useBatchCountriesQuery, {
                arguments: { songs: [song], dateFilter: PAST28, storeFilter: selectedStoreIds, sectionData: { topCountriesPotMetric: DOWNLOADS } },
                mocks: [mockQuery('SoundRecordingCountryDownloadsQuery', {
                    variables: { isrc: CODE1, startDate: HIGHWATER_MARK, days: -28, storeIds: selectedStoreIds },
                    result: {
                        soundRecording: {
                            isrc: CODE1,
                            analytics: {
                                topCountriesByDownloads: {
                                    countries: [{ countryCode: 'UA', downloads: 100 }],
                                    sources: []
                                }
                            }
                        }
                    }
                })]
            });
            const expectedCountryRecord: TopCountry = {
                alpha3: 'UKR',
                code: 'UA',
                highlight: false,
                name: 'Ukraine',
                position: 1,
                value: 100,
            };
            const expectedResult = {
                count: 5,
                loading: false,
                data: [{
                    isrc: CODE1,
                    countries: [expectedCountryRecord]
                }],
            };

            expect(result).toEqual(expectedResult);
        });
    });

    describe('with selected songs', () => {
        test('returns playlists data for each song', async () => {
            const songs = selectedSongIds.map(id => ({
                id,
                data: createSoundRecordingMetadata({
                    isrc: id,
                    products: [
                        { genreId: null, releaseDate: '01-01-2019', deletions: 'N' }
                    ]
                }).soundRecording
            })) as ComparisonSong[];

            const expectedResult = {
                loading: false,
                count: 5,
                data: selectCountryStreamsRecords(songs, songs.map(() => ({
                    data: createSoundRecordingCountryStreams(),
                    loading: false,
                    networkStatus: 7,
                    stale: false
                })))
            };

            const result = await executeHook(useBatchCountriesQuery, {
                arguments: { songs, dateFilter: PAST28, storeFilter: selectedStoreIds },
                waitUntilMatch: expectedResult,
                mocks: selectedSongIds.map(isrc =>
                    mockQuery('SoundRecordingCountryStreamsQuery', {
                        variables: { isrc, startDate: HIGHWATER_MARK, days: -28, storeIds: selectedStoreIds, offset: 0 }
                    }))
            });

            expect(result).toEqual(expectedResult);
        });
    });
});
