import React from 'react'
import { mount } from '../../test/utils'

import { Checkbox } from '../Checkbox'
import { Form } from '../../Form/Form'
import { InlineError } from '../../InlineError/InlineError'

const FormWrapper = ({ children }: any) => (
  <Form onSubmit={() => { }}>{children}</Form>
)

describe('<Checkbox />', () => {
  it('values are pass to input component', () => {
    const input = mount(
      <FormWrapper>
        <Checkbox checked name="Checkbox" value="Value" />
      </FormWrapper>
    )
    expect(input).toContainReactComponent('input', {
      checked: true,
      name: 'Checkbox'
    })
  })
  describe('onChange()', () => {
    it('is called with the updated checked value of the input on click', () => {
      const spy = jest.fn()
      const element = mount(
        <FormWrapper>
          {' '}
          <Checkbox name="Checkbox" onChange={spy} />
        </FormWrapper>
      )

        ; (element.find('input')!.domNode as HTMLInputElement).checked = true
      const event = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
      })
      element.find('input')!.domNode?.dispatchEvent(event)

      expect(spy).toHaveBeenCalledWith(false)
    })

    it('sets focus on the input when checkbox is toggled off', () => {
      const checkbox = mount(
        <FormWrapper>
          {' '}
          <Checkbox checked name="Checkbox" onChange={() => { }} />
        </FormWrapper>
      )
      checkbox.find('input')!.trigger('onClick')

      expect(document.activeElement).toBe(checkbox.find('input')!.domNode)
    })

    it('is not called when disabled', () => {
      const spy = jest.fn()
      const checkbox = mount(
        <FormWrapper>
          <Checkbox name="label" disabled onChange={spy} />
        </FormWrapper>
      )
      checkbox.find('input')!.trigger('onClick', {
        stopPropagation: () => { }
      })
      expect(spy).not.toHaveBeenCalled()
    })

    it('is not called when onChange is not passed', () => {
      const spy = jest.fn()
      const checkbox = mount(
        <FormWrapper>
          <Checkbox name="label" />
        </FormWrapper>
      )
      checkbox.find('input')!.trigger('onClick', {
        stopPropagation: () => { }
      })
      expect(spy).not.toHaveBeenCalled()
    })
  })

  describe('disabled', () => {
    it('sets the disabled attribute on the input', () => {
      const form = mount(
        <FormWrapper>
          <Checkbox name="label" disabled />
        </FormWrapper>
      )

      expect(form).toContainReactComponent('input', {
        disabled: true
      })
    })
  })

  describe('helpText', () => {
    it('renders the help text', () => {
      const form = mount(
        <FormWrapper>
          <Checkbox name="label" helpText="Lorem ipsum" />
        </FormWrapper>
      )

      expect(form.find('div')).toContainReactText('Lorem ipsum')
    })
  })

  describe('error', () => {
    it('display error when form validation fails and it was touched', () => {
      const validate = () => 'Error Message'

      const form = mount(
        <FormWrapper>
          <Checkbox name="checkbox" validate={validate} />
        </FormWrapper>
      )
      form.find('input')!.trigger('onBlur')
      expect(form).toContainReactComponent(InlineError, {
        message: 'Error Message'
      })
    })

    it('does not display error when form validation fails and it was not touched', () => {
      const validate = () => 'Error Message'

      const form = mount(
        <FormWrapper>
          <Checkbox name="checkbox" validate={validate} />
        </FormWrapper>
      )
      expect(form).not.toContainReactComponent(InlineError, {
        message: 'Error Message'
      })
    })

    it('does not display error when form validation fails and it error si boolean', () => {
      const validate = () => true

      const form = mount(
        <FormWrapper>
          <Checkbox name="checkbox" validate={validate} />
        </FormWrapper>
      )
      form.find('input')!.trigger('onBlur')
      expect(form).not.toContainReactComponent(InlineError)
    })

    it('display both error and help text when form validation fails and it was touched', () => {
      const validate = () => 'Error Message'

      const form = mount(
        <FormWrapper>
          <Checkbox
            name="checkbox"
            validate={validate}
            helpText="Lorem ipsum"
          />
        </FormWrapper>
      )
      form.find('input')!.trigger('onBlur')
      expect(form).toContainReactComponent(InlineError, {
        message: 'Error Message'
      })
      expect(form.find('div')).toContainReactText('Lorem ipsum')
    })
  })
})
