import React from 'react';
import { waitFor, fireEvent } from '@testing-library/react';
import renderWithTheme from '../../../../testUtils/renderWithTheme';

import DoubleCalendar from '../DoubleCalendar';

describe('rendering', () => {
  it('renders double calendar', async () => {
    const { getAllByText, getByTestId } = renderWithTheme(
      <DoubleCalendar
        startDate={new Date(2021, 1, 19)}
        endDate={new Date(2021, 1, 25)}
        minDate={new Date(2021, 1, 1)}
        maxDate={new Date(2021, 1, 26)}
        dateClickCount={0}
        isSettingStartDate={false}
        isSettingEndDate={false}
      />
    );

    await waitFor(() => {
      const firstMonthSelect = getByTestId('first-month-select');
      const firstYearSelect = getByTestId('first-year-select');
      const secondMonthSelect = getByTestId('second-month-select');
      const secondYearSelect = getByTestId('second-year-select');

      expect(firstMonthSelect).toSelectItem('Feb');
      expect(firstYearSelect).toSelectItem('2021');
      expect(secondMonthSelect).toSelectItem('Mar');
      expect(secondYearSelect).toSelectItem('2021');

      // shows days of week
      expect(getAllByText('Su').length).toBe(2);
      expect(getAllByText('Mo').length).toBe(2);
      expect(getAllByText('Tu').length).toBe(2);
      expect(getAllByText('We').length).toBe(2);
      expect(getAllByText('Th').length).toBe(2);
      expect(getAllByText('Fr').length).toBe(2);
      expect(getAllByText('Sa').length).toBe(2);
      // shows normal/selected dates
      expect(getAllByText('19').length).toBe(2);
      expect(getAllByText('23').length).toBe(2);
      expect(getAllByText('25').length).toBe(2);
      // shows disabled date
      expect(getAllByText('31').length).toBe(2);
      expect(getAllByText('26').length).toBe(2);
    });
  });
});

describe('interaction', () => {
  it('allows to select month and year', async () => {
    const { getAllByText, getByTestId } = renderWithTheme(
      <DoubleCalendar
        startDate={new Date(2021, 4, 19)}
        endDate={new Date(2021, 4, 25)}
        dateClickCount={0}
        isSettingStartDate={false}
        isSettingEndDate={false}
      />
    );
    const firstMonthSelect = getByTestId('first-month-select');
    const firstYearSelect = getByTestId('first-year-select');
    const secondMonthSelect = getByTestId('second-month-select');
    const secondYearSelect = getByTestId('second-year-select');

    fireEvent.click(firstMonthSelect);
    fireEvent.click(getAllByText('Dec')[0]);

    await waitFor(() => {
      expect(firstMonthSelect).toSelectItem('Dec');
      expect(firstYearSelect).toSelectItem('2021');
      expect(secondMonthSelect).toSelectItem('Jan');
      expect(secondYearSelect).toSelectItem('2022');
    });

    fireEvent.click(secondMonthSelect);
    fireEvent.click(getAllByText('May')[1]);

    await waitFor(() => {
      expect(firstMonthSelect).toSelectItem('Apr');
      expect(firstYearSelect).toSelectItem('2022');
      expect(secondMonthSelect).toSelectItem('May');
      expect(secondYearSelect).toSelectItem('2022');
    });

    fireEvent.click(firstMonthSelect);
    fireEvent.click(getAllByText('2023')[0]);

    await waitFor(() => {
      expect(firstYearSelect).toSelectItem('2023');
      expect(secondYearSelect).toSelectItem('2023');
    });

    fireEvent.click(secondYearSelect);
    fireEvent.click(getAllByText('2025')[1]);

    await waitFor(() => {
      expect(firstYearSelect).toSelectItem('2025');
      expect(secondYearSelect).toSelectItem('2025');
    });
  });

  it('allows to select a date', async () => {
    const onSelectDate = jest.fn();
    const { getAllByText, getByTestId } = renderWithTheme(
      <DoubleCalendar
        startDate={new Date(2021, 4, 19)}
        endDate={new Date(2021, 4, 25)}
        dateClickCount={0}
        isSettingStartDate={false}
        isSettingEndDate={false}
        onSelectDate={onSelectDate}
      />
    );
    fireEvent.click(getByTestId('first-month-select'));
    fireEvent.click(getAllByText('Dec')[0]);
    fireEvent.click(getAllByText(2)[2]);

    await waitFor(() => {
      expect(onSelectDate).toHaveBeenCalledTimes(1);
      expect(onSelectDate).toHaveBeenCalledWith(new Date(2022, 0, 2));
    });
  });

  it('does not allow to select a new date out of range', async () => {
    const onSelectDate = jest.fn();
    const { getAllByText } = renderWithTheme(
      <DoubleCalendar
        startDate={new Date(2021, 4, 19)}
        endDate={new Date(2021, 4, 25)}
        minDate={new Date(2021, 4, 10)}
        maxDate={new Date(2021, 4, 30)}
        dateClickCount={0}
        isSettingStartDate={false}
        isSettingEndDate={false}
        onSelectDate={onSelectDate}
      />
    );

    fireEvent.click(getAllByText(2)[1]);

    await waitFor(() => {
      expect(onSelectDate).not.toHaveBeenCalled();
    });
  });
});
