import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { render } from '@testing-library/react';
import { STORE_SPOTIFY, STORE_APPLE_MUSIC } from 'src/constants/stores';
import { PlaylistData } from 'src/selectors';
import { formatPercentage } from 'src/utils/formatNumber';
import { EMPTY_CHAR } from 'src/components/metric';
import TopPlaylistItem, { Props, TEST_ID, TERM_FOLLOWERS_ONE, TERM_FOLLOWERS_MANY, CLASSNAME } from '../TopPlaylistItem';

describe('<TopPlaylistItem>', () => {
    const playlist: PlaylistData = {
        playlistName: 'Indie Gaming',
        playlistImage: 'https://dhfsk7jl2g0km.cloudfront.net/playlist-37i9dQZF1DX4geSlFB9288.jpeg',
        streams: 12,
        storeId: STORE_SPOTIFY,
        playlistUrl: 'spotify-personalized-playlist:dailyMix',
    };
    const defaultProps: Props = {
        index: 0,
        totalStreams: 101,
        order: 1,
        playlistsCount: 1,
        playlist,
    };
    const renderMocked = (props?: Partial<Props>) =>
        render(<TopPlaylistItem {...defaultProps} {...props} />);

    test('renders TopPlaylistItem', () => {
        const component = renderMocked();
        const topPlaylistItem = component.getByTestId(TEST_ID);
        const image = component.container.getElementsByClassName(`${CLASSNAME}-image`);
        const name = component.getByText('Indie Gaming');
        const precentage = component.getByText(formatPercentage(0.119));
        const percentageOnly = component.container.getElementsByClassName('ProgressBar-percentage-only');

        expect(topPlaylistItem).toBeVisible();
        expect(image.length).toBe(1);
        expect(image[0]).toBeVisible();
        expect(image[0].getAttribute('src')).toBe(playlist.playlistImage);
        expect(name).toBeVisible();
        expect(name.getAttribute('href')).toBeNull();
        expect(precentage).toBeVisible();
        expect(percentageOnly.length).toBe(0);
    });

    test.each([
        ['Spotify Icon', STORE_SPOTIFY, 'Icons-spotify'],
        ['AppleMusic Icon', STORE_APPLE_MUSIC, 'Icons-apple-music'],
    ])('renders TopPlaylistItem with %s', (_, storeId, iconClassName) => {
        const { container } = renderMocked({ playlist: { ...playlist, storeId: storeId as number } });
        const icon = container.getElementsByClassName(iconClassName as string)[0];
        expect(icon).toBeDefined();
    });

    test('does not render store icon for TopPlaylistItem if unknow store provided', () => {
        const { container } = renderMocked({ playlist: { ...playlist, storeId: -1 } });
        const imageContainer = container.getElementsByClassName(`${TEST_ID}-store-icon`);

        expect(imageContainer.length).toBe(0);
    });

    test('renders empty thumbnail for TopPlaylistItem without image', () => {
        const { container } = renderMocked({ playlist: { ...playlist, playlistImage: '' } });
        const emptyPlaceholder = container.getElementsByClassName(`${TEST_ID}-image-empty`);

        expect(emptyPlaceholder.length).toBe(1);
    });

    test('renders empty char for TopPlaylistItem without streams', () => {
        const { container } = renderMocked({ playlist: { ...playlist, streams: undefined } });
        const emptyPlaceholder = container.getElementsByClassName(`${TEST_ID}-streams`)[0];

        expect(emptyPlaceholder.textContent).toBe(EMPTY_CHAR);
    });

    test('does not render progress bar for TopPlaylistItem if 4 or more playlists selected', () => {
        const { container } = renderMocked({ playlistsCount: 4 });
        const percentageOnlyValue = container.getElementsByClassName('ProgressBar-percentage-only');
        const percentageBar = container.getElementsByClassName('ProgressBar-bar');
        expect(percentageOnlyValue.length).toBe(1);
        expect(percentageBar.length).toBe(0);
    });

    test('does not render badge for TopPlaylistItem if order not specified', () => {
        const { container } = renderMocked({ order: undefined });
        const emptyPlaceholder = container.getElementsByClassName(`${TEST_ID}-badge`);

        expect(emptyPlaceholder.length).toBe(0);
    });

    test('renders one follower', () => {
        const component = renderMocked({ playlist: { ...playlist, followers: 1 } });
        const followersNode = component.getByText(TERM_FOLLOWERS_ONE);

        expect(followersNode).toBeVisible();
    });

    test('renders 12345 followers', () => {
        const component = renderMocked({ playlist: { ...playlist, followers: 12345 } });
        const followersNode = component.getByText(TERM_FOLLOWERS_MANY);

        expect(followersNode).toBeVisible();
    });

    test.each([
        ['Zero', 0],
        ['no', undefined],
    ])('renders dash if %s followers specified', (_, followers) => {
        const component = renderMocked({ playlist: { ...playlist, followers } });
        const followersNode = component.getByText(EMPTY_CHAR);

        expect(followersNode).toBeVisible();
    });

    test('renders playlist URL', () => {
        const playlistUrl = 'http://www.example.org';
        const component = renderMocked({ playlist: { ...playlist, playlistUrl } });
        const url = component.getByText(playlist.playlistName);

        expect(url).toBeVisible();
        expect(url.getAttribute('href')).toBe(playlistUrl);
    });

});
