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

import TimePicker from '..';
import Typography from '../../Typography';
import { noop } from '../../../fp/function';

describe('rendering', () => {
  it('renders passed value to input', async () => {
    const { getByDisplayValue } = renderWithTheme(
      <TimePicker value="12:30:01" onChange={noop} />
    );

    await waitFor(() => {
      expect(getByDisplayValue('12:30:01')).toBeInTheDocument();
    });
  });
});

describe('interaction', () => {
  it('allows to blur', async () => {
    const onBlur = jest.fn();
    const { getByLabelText } = renderWithTheme(
      <Typography.Text tagName="label">
        Pick time
        <TimePicker onBlur={onBlur} withSeconds with12Hours />
      </Typography.Text>
    );

    await waitFor(() => {
      expect(getByLabelText(/Pick time/)).toBeInTheDocument();
    });

    fireEvent.focus(getByLabelText(/Pick time/));

    fireEvent.blur(getByLabelText(/Pick time/));
    expect(onBlur).toHaveBeenCalledTimes(1);
  });

  describe('withSeconds=true & with12Hours=true', () => {
    it('calls onChange with correct format', async () => {
      const onChange = jest.fn();
      const { getByLabelText, findAllByText, findByText } = renderWithTheme(
        <Typography.Text tagName="label">
          Pick time
          <TimePicker onChange={onChange} withSeconds with12Hours />
        </Typography.Text>
      );

      await waitFor(() => {
        expect(getByLabelText(/Pick time/)).toBeInTheDocument();
      });

      fireEvent.focus(getByLabelText(/Pick time/));

      const [hour] = await findAllByText('08');
      const [, minute] = await findAllByText('10');
      const [, second] = await findAllByText('56');
      const am = await findByText('AM');

      fireEvent.click(hour);
      fireEvent.click(minute);
      fireEvent.click(second);
      fireEvent.click(am);

      fireEvent.blur(getByLabelText(/Pick time/));

      expect(onChange).toHaveBeenCalledWith('08:10:56 AM');
    });
  });

  describe('withSeconds=false & with12Hours=true', () => {
    it('calls onChange with correct format', async () => {
      const onChange = jest.fn();
      const { getByLabelText, findAllByText, findByText } = renderWithTheme(
        <Typography.Text tagName="label">
          Pick time
          <TimePicker onChange={onChange} withSeconds={false} with12Hours />
        </Typography.Text>
      );

      await waitFor(() => {
        expect(getByLabelText(/Pick time/)).toBeInTheDocument();
      });

      fireEvent.focus(getByLabelText(/Pick time/));

      const [hour] = await findAllByText('08');
      const [, minute] = await findAllByText('10');
      const am = await findByText('AM');

      fireEvent.click(hour);
      fireEvent.click(minute);
      fireEvent.click(am);

      fireEvent.blur(getByLabelText(/Pick time/));

      expect(onChange).toHaveBeenCalledWith('08:10 AM');
    });
  });

  describe('withSeconds=true & with12Hours=false', () => {
    it('calls onChange with correct format', async () => {
      const onChange = jest.fn();
      const { getByLabelText, findAllByText } = renderWithTheme(
        <Typography.Text tagName="label">
          Pick time
          <TimePicker onChange={onChange} withSeconds with12Hours={false} />
        </Typography.Text>
      );

      await waitFor(() => {
        expect(getByLabelText(/Pick time/)).toBeInTheDocument();
      });

      fireEvent.focus(getByLabelText(/Pick time/));

      const [hour] = await findAllByText('13');
      const [, minute] = await findAllByText('10');
      const [, second] = await findAllByText('56');

      fireEvent.click(hour);
      fireEvent.click(minute);
      fireEvent.click(second);

      fireEvent.blur(getByLabelText(/Pick time/));

      expect(onChange).toHaveBeenCalledWith('13:10:56');
    });
  });

  describe('withSeconds=false & with12Hours=false', () => {
    it('calls onChange with correct format', async () => {
      const onChange = jest.fn();
      const { getByLabelText, findAllByText } = renderWithTheme(
        <Typography.Text tagName="label">
          Pick time
          <TimePicker
            onChange={onChange}
            withSeconds={false}
            with12Hours={false}
          />
        </Typography.Text>
      );

      await waitFor(() => {
        expect(getByLabelText(/Pick time/)).toBeInTheDocument();
      });

      fireEvent.focus(getByLabelText(/Pick time/));

      const [hour] = await findAllByText('13');
      const [, minute] = await findAllByText('10');

      fireEvent.click(hour);
      fireEvent.click(minute);

      fireEvent.blur(getByLabelText(/Pick time/));

      expect(onChange).toHaveBeenCalledWith('13:10');
    });
  });

  describe('format is specified', () => {
    it('calls onChange with specified format', async () => {
      const onChange = jest.fn();
      const { getByLabelText, findAllByText, findByText } = renderWithTheme(
        <Typography.Text tagName="label">
          Pick time
          <TimePicker onChange={onChange} format="hh/mm/ss BBBBB" />
        </Typography.Text>
      );

      await waitFor(() => {
        expect(getByLabelText(/Pick time/)).toBeInTheDocument();
      });

      fireEvent.focus(getByLabelText(/Pick time/));

      const [hour] = await findAllByText('08');
      const [, minute] = await findAllByText('10');
      const [, second] = await findAllByText('56');
      const am = await findByText('AM');

      fireEvent.click(hour);
      fireEvent.click(minute);
      fireEvent.click(second);
      fireEvent.click(am);

      fireEvent.blur(getByLabelText(/Pick time/));

      expect(onChange).toHaveBeenCalledWith('08/10/56 in the morning');
    });
  });
});
