import React from 'react';
import { fireEvent, render as renderDom, screen, act } from '@testing-library/react';
import SpotifyPlayer, { TEST_ID } from '../spotifyPlayer';
import SpotifyWebApiInstance from '../spotifyWebApi';
import { wait } from './wait';

describe('<SpotifyPlayer>', () => {
    const render = async () => {
        renderDom(<SpotifyPlayer />);

        await act(async () => await wait());
    };

    const currentTrack: Spotify.PlayerTrack = {
        album: { images: [{ url: 'IMAGE1_URL' }], name: 'Album 1' },
        artists: [{ name: 'Artist 1', uri: 'ARTIST1_URL' }],
        id: 'TRACK_ID',
        name: 'Track 1',
        uri: 'TRACK1_URL',
        linked_from: { uri: 'TRACK1_LINKED_URL' },
    };

    const mockApi = () => {
        const player: Spotify.Player = {
            ...SpotifyWebApiInstance.player,
            togglePlay: jest.fn(),
            addListener: jest.fn(),
            connect: jest.fn(),
            disconnect: jest.fn(),
            removeListener: jest.fn(),
            getCurrentState: async () =>
                await Promise.resolve<Spotify.PlayerState>({
                    paused: true,
                    device_id: 'DEVICE_ID',
                    message: 'Message',
                    track_window: { current_track: currentTrack },
                }),
        };
        SpotifyWebApiInstance.player = player;
    };
    let defaultPlayer: Spotify.Player | null = null;

    beforeEach(() => {
        defaultPlayer = SpotifyWebApiInstance.player;
        mockApi();
    });

    afterEach(() => {
        jest.restoreAllMocks();
        SpotifyWebApiInstance.player = defaultPlayer;
    });

    test('renders default component', async () => {
        await render();

        expect(screen.getByTestId(TEST_ID)).toBeInTheDocument();
    });

    test('renders track title', async () => {
        await render();

        expect(screen.getByText(currentTrack.name)).toBeInTheDocument();
    });

    test('renders artist', async () => {
        await render();

        expect(screen.getByText(currentTrack.artists[0].name)).toBeInTheDocument();
    });

    test('renders image', async () => {
        await render();

        expect(screen.getByTestId('CoverArt').childNodes[0]).toHaveClass('CoverArt-image');
    });

    test('renders link', async () => {
        await render();

        expect(screen.getByRole('link').getAttribute('href')).toContain(`track/${currentTrack.id}`);
    });

    test('handles close click', async () => {
        await render();
        const closeButton = screen.getAllByRole('button')[1];

        fireEvent.click(closeButton);

        expect(screen.queryByTestId(TEST_ID)).toBeNull();
    });
});
