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

import Switch from '..';
import Typography from '../../Typography';

describe('rendering', () => {
  it('renders switch as input', () => {
    const { getByLabelText } = renderWithTheme(
      <Typography.Text tagName="label">
        Toggle
        <Switch />
      </Typography.Text>
    );
    expect(getByLabelText('Toggle')).toBeInTheDocument();
  });

  describe('Icon', () => {
    it('renders icon when icon has value', () => {
      const { getByTestId } = renderWithTheme(
        <Typography.Text tagName="label">
          Toggle
          <Switch icon="dollar-sign" />
        </Typography.Text>
      );

      expect(getByTestId('switch-icon')).toBeInTheDocument();
    });

    it('does not render icon when icon is undefined', () => {
      const { queryByTestId } = renderWithTheme(
        <Typography.Text tagName="label">
          Toggle
          <Switch />
        </Typography.Text>
      );

      expect(queryByTestId('switch-icon')).not.toBeInTheDocument();
    });
  });

  describe('Loading', () => {
    it('renders loading icon when loading is true', () => {
      const { getByTestId } = renderWithTheme(
        <Typography.Text tagName="label">
          Toggle
          <Switch loading />
        </Typography.Text>
      );

      expect(getByTestId('loading-icon')).toBeInTheDocument();
    });

    it('does not render loading icon when loading is false', () => {
      const { queryByTestId } = renderWithTheme(
        <Typography.Text tagName="label">
          Toggle
          <Switch loading={false} />
        </Typography.Text>
      );

      expect(queryByTestId('loading-icon')).not.toBeInTheDocument();
    });
  });
});

describe('interaction', () => {
  it('toggles state as an uncontrolled component', () => {
    const onChange = jest.fn();
    const { getByLabelText } = renderWithTheme(
      <Typography.Text tagName="label">
        Toggle
        <Switch onChange={(e): void => onChange(e.target.checked)} />
      </Typography.Text>
    );
    expect((getByLabelText('Toggle') as HTMLInputElement).checked).toBe(false);
    fireEvent.click(getByLabelText('Toggle'));
    expect((getByLabelText('Toggle') as HTMLInputElement).checked).toBe(true);
    fireEvent.click(getByLabelText('Toggle'));
    expect((getByLabelText('Toggle') as HTMLInputElement).checked).toBe(false);
  });

  it('allows to be controlled', () => {
    const onChange = jest.fn();
    const { getByLabelText } = renderWithTheme(
      <Typography.Text tagName="label">
        Toggle
        <Switch
          checked={false}
          onChange={(e): void => onChange(e.target.checked)}
        />
      </Typography.Text>
    );
    expect((getByLabelText('Toggle') as HTMLInputElement).checked).toBe(false);
    fireEvent.click(getByLabelText('Toggle'));
    expect(onChange).toHaveBeenCalledTimes(1);
    expect(onChange).toHaveBeenCalledWith(true);

    fireEvent.click(getByLabelText('Toggle'));
    expect(onChange).toHaveBeenCalledTimes(2);
    expect(onChange).toHaveBeenCalledWith(true);
  });
});
