import React from 'react';
import { render as trender } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { axe, toHaveNoViolations } from 'jest-axe';
import userEvent from '@testing-library/user-event';
import { FormCheck } from './FormCheck';

expect.extend(toHaveNoViolations);

function render({
  label = 'FormCheck', name = 'form_name', ...props
}) {
  return trender(
    <FormCheck id={name} name={name} labelProps={{ htmlFor: name }} {...props}>{label}</FormCheck>
  );
}

describe('FormCheck', () => {
  test('should be well formed ', async () => {
    const { container } = render({});
    const results = await axe(container);
    expect(results).toHaveNoViolations();
  });

  test('should have more than one case checked when is checkbox', () => {
    const { getByLabelText } = trender(
      <>
        <FormCheck name="name" id="1" labelProps={{ htmlFor: '1' }}>1</FormCheck>
        <FormCheck name="name" id="2" labelProps={{ htmlFor: '2' }}>2</FormCheck>
        <FormCheck name="name" id="3" labelProps={{ htmlFor: '3' }}>3</FormCheck>
      </>
    );
    const form1 = getByLabelText(/1/i);
    const form2 = getByLabelText(/2/i);
    const form3 = getByLabelText(/3/i);
    expect(form1).toHaveProperty('checked', false);
    expect(form2).toHaveProperty('checked', false);
    expect(form3).toHaveProperty('checked', false);

    userEvent.click(form1);
    expect(form1).toHaveProperty('checked', true);

    userEvent.click(form2);
    expect(form2).toHaveProperty('checked', true);
    expect(form1).toHaveProperty('checked', true);
    expect(form3).toHaveProperty('checked', false);
  });

  test('should have only one case checked when is radio', () => {
    const { getByLabelText } = trender(
      <>
        <FormCheck name="name" id="1" labelProps={{ htmlFor: '1' }} isRadio>1</FormCheck>
        <FormCheck name="name" id="2" labelProps={{ htmlFor: '2' }} isRadio>2</FormCheck>
        <FormCheck name="name" id="3" labelProps={{ htmlFor: '3' }} isRadio>3</FormCheck>
      </>
    );
    const form1 = getByLabelText(/1/i);
    const form2 = getByLabelText(/2/i);
    const form3 = getByLabelText(/3/i);
    expect(form1).toHaveProperty('checked', false);
    expect(form2).toHaveProperty('checked', false);
    expect(form3).toHaveProperty('checked', false);

    userEvent.click(form1);
    expect(form1).toHaveProperty('checked', true);

    userEvent.click(form2);
    expect(form2).toHaveProperty('checked', true);
    expect(form1).toHaveProperty('checked', false);
    expect(form3).toHaveProperty('checked', false);
  });

  test('should have a type checkbox', () => {
    const { getByLabelText } = render({});
    const input = getByLabelText(/FormCheck/i);
    expect(input).toHaveAttribute('type', 'checkbox');
    expect(input).toHaveProperty('checked', false);
  });

  test('should have a default checked option', () => {
    const { getByLabelText } = render({ defaultChecked: true });
    const input = getByLabelText(/FormCheck/i);
    expect(input).toHaveAttribute('checked');
    expect(input).toHaveProperty('checked', true);
  });

  test('should have a disabled option', () => {
    const { getByLabelText } = render({ disabled: true });
    const input = getByLabelText(/FormCheck/i);
    expect(input).toHaveAttribute('disabled');
  });

  test('should have a radio option', () => {
    const { getByLabelText } = render({ isRadio: true });
    const input = getByLabelText(/FormCheck/i);
    expect(input).toHaveAttribute('type', 'radio');
  });

  test('should have an inline option', () => {
    const { getByTestId } = render({ isInline: true });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--inline');
  });

  test('should have a variant button option', () => {
    const { getByTestId } = render({ variant: 'button' });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--button');
  });

  test('should have a variant button-light option', () => {
    const { getByTestId } = render({ variant: 'button-light' });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--button-light');
  });

  test('should have a variant button-denim-300 option', () => {
    const { getByTestId } = render({ variant: 'button-denim-300' });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--button-denim-300');
  });

  test('should have a variant toogle option', () => {
    const { getByTestId } = render({ variant: 'toggle' });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--toggle');
  });

  test('should have a different color options', async () => {
    const { rerender, getByTestId } = render({ color: 'success' });
    const label = getByTestId('label-form_name');
    expect(label).toHaveClass('as--success');
    await rerender(<FormCheck id="form_name" name="form_name" color="warning" labelProps={{ htmlFor: 'form_name' }}>FormCheck</FormCheck>);
    expect(label).toHaveClass('as--warning');
    await rerender(<FormCheck id="form_name" name="form_name" color="danger" labelProps={{ htmlFor: 'form_name' }}>FormCheck</FormCheck>);
    expect(label).toHaveClass('as--danger');
  });
});
