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

import WeekPicker from '../WeekPicker';

describe('rendering', () => {
  it('renders date input and calendar', async () => {
    const { getByDisplayValue, getByTestId } = renderWithTheme(
      <WeekPicker value="Week 01, 2021" />
    );

    await waitFor(() => {
      expect(getByDisplayValue('Week 01, 2021')).toBeInTheDocument();
    });

    userEvent.click(getByDisplayValue('Week 01, 2021'));

    await waitFor(() => {
      const monthSelect = getByTestId('month-select');
      expect(monthSelect).toSelectItem('Dec');
      const yearSelect = getByTestId('year-select');
      expect(yearSelect).toSelectItem('2020');
    });
  });
});

describe('interaction', () => {
  it('allows to blur', async () => {
    const onBlur = jest.fn();

    const { getByDisplayValue } = renderWithTheme(
      <WeekPicker value="Week 01, 2021" onBlur={onBlur} />
    );

    userEvent.click(getByDisplayValue('Week 01, 2021'));
    userEvent.click(document.body);
    expect(onBlur).toHaveBeenCalledTimes(1);
  });

  it('allows to pick a week', async () => {
    const onChange = jest.fn();
    const { getByDisplayValue, getByText } = renderWithTheme(
      <WeekPicker value="Week 01, 2021" onChange={onChange} />
    );

    userEvent.click(getByDisplayValue('Week 01, 2021'));
    userEvent.click(getByText('21'));

    await waitFor(() => {
      expect(onChange).toHaveBeenCalledTimes(1);
      expect(onChange).toHaveBeenCalledWith('Week 52, 2020');
    });
  });

  it('allows to pick a week by changing input value', async () => {
    const onChange = jest.fn();
    const { getByPlaceholderText } = renderWithTheme(
      <WeekPicker onChange={onChange} placeholder="Birthday" />
    );

    userEvent.type(getByPlaceholderText('Birthday'), 'Week 01, 2021');

    await waitFor(() => {
      expect(onChange).toHaveBeenCalledTimes(13);
      expect(onChange).toHaveBeenCalledWith('W');
      expect(onChange).toHaveBeenCalledWith('e');
      expect(onChange).toHaveBeenCalledWith('k');
      expect(onChange).toHaveBeenCalledWith('0');
      expect(onChange).toHaveBeenCalledWith('1');
      expect(onChange).toHaveBeenCalledWith('2');
    });
  });

  it('calendar shows current date when input value of datepicker is invalid format', async () => {
    jest.useFakeTimers('modern');
    jest.setSystemTime(new Date(2022, 1, 19));

    const { getByText, getByDisplayValue, getByTestId } = renderWithTheme(
      <WeekPicker value="Week 123" />
    );

    userEvent.click(getByDisplayValue('Week 123'));

    await waitFor(() => {
      const monthSelect = getByTestId('month-select');
      expect(monthSelect).toSelectItem('Feb');
      const yearSelect = getByTestId('year-select');
      expect(yearSelect).toSelectItem('2022');
      expect(getByText('19')).toBeInTheDocument();
    });
  });

  it('does not allow to edit disabled DatePicker', async () => {
    const onChange = jest.fn();
    const { queryByText, getByDisplayValue } = renderWithTheme(
      <WeekPicker value="Week 01, 2021" onChange={onChange} disabled />
    );

    userEvent.click(getByDisplayValue('Week 01, 2021'));

    await waitFor(() => {
      expect(queryByText('Su')).not.toBeInTheDocument();
    });

    userEvent.type(getByDisplayValue('Week 01, 2021'), 'Week 02, 2021');

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