import React from 'react';
import userEvent from '@testing-library/user-event';
import renderWithTheme from '../../../testUtils/renderWithTheme';

import Carousel from '../index';

describe('Carousel', () => {
  const collection = [
    {
      id: 1,
      content: <p>Slide 1</p>,
    },
    {
      id: 2,
      content: <p>Slide 2</p>,
    },
  ];

  it('renders spinner when loading', () => {
    const { getByTestId, queryByTestId } = renderWithTheme(
      <Carousel collection={collection} loading />
    );

    expect(getByTestId('spinner')).toBeInTheDocument();
    expect(queryByTestId('slide-collection')).not.toBeInTheDocument();
  });

  it('renders correctly', () => {
    const { getByTestId, queryByTestId } = renderWithTheme(
      <Carousel collection={collection} />
    );

    // render 2 slides
    expect(queryByTestId('spinner')).not.toBeInTheDocument();
    expect(getByTestId('slide-1')).toBeInTheDocument();
    expect(getByTestId('slide-2')).toBeInTheDocument();

    // render navigation buttons and navigation dots
    expect(getByTestId('previous-slide-button')).toBeInTheDocument();
    expect(getByTestId('next-slide-button')).toBeInTheDocument();
    expect(getByTestId('dot-navigation-button-1')).toBeInTheDocument();
    expect(getByTestId('dot-navigation-button-2')).toBeInTheDocument();
  });

  it('allows to navigate through slides', () => {
    const { getByTestId } = renderWithTheme(
      <Carousel collection={collection} />
    );

    const slideCollection = getByTestId('slide-collection');
    const preSlideBtn = getByTestId('previous-slide-button');
    const nextSlideBtn = getByTestId('next-slide-button');
    const slide1Btn = getByTestId('dot-navigation-button-1');
    const slide2Btn = getByTestId('dot-navigation-button-2');

    // Slide 1 is active
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });

    // Go to slide 2
    userEvent.click(slide2Btn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-100%)' });

    // Go to slide 1
    userEvent.click(slide1Btn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });

    // Go to next slide
    userEvent.click(nextSlideBtn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-100%)' });
    userEvent.click(nextSlideBtn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });

    // Go to previous slide
    userEvent.click(preSlideBtn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-100%)' });
    userEvent.click(preSlideBtn);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });
  });

  it('goes through slides automatically', async () => {
    jest.useFakeTimers();

    const { getByTestId } = renderWithTheme(
      <Carousel collection={collection} autoPlay />
    );
    const slideCollection = getByTestId('slide-collection');

    // Slide 1 is active
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });

    // Automatically goes to slide 2
    jest.advanceTimersByTime(2000);

    expect(slideCollection).toHaveStyle({ transform: 'translateX(-100%)' });

    // Stop going through slide when hovering the slide
    userEvent.hover(slideCollection);
    expect(slideCollection).toHaveStyle({ transform: 'translateX(-100%)' });

    // Re-create interval to go through slide;
    userEvent.unhover(slideCollection);
    jest.advanceTimersByTime(2000);

    expect(slideCollection).toHaveStyle({ transform: 'translateX(-0%)' });
  });
});
