// Directives
import Ripple from '../'

// Utilities
import { mount } from '@vue/test-utils'
import { defineComponent } from 'vue'

const testComponent = defineComponent({
  directives: { Ripple },
  template: '<div class="a" v-ripple />',
})

describe('v-ripple', () => {
  it('with no value should be enabled', () => {
    const wrapper = mount(testComponent)

    expect(wrapper.element._ripple?.enabled).toBe(true)
  })

  it('should update element property reactively', async () => {
    const wrapper = mount({
      directives: { Ripple },
      props: {
        ripple: {
          type: Boolean,
          default: true,
        },
      },
      template: '<div class="a" v-ripple="ripple" />',
    })
    const el = wrapper.element

    expect(el._ripple?.enabled).toBe(true)

    await wrapper.setProps({ ripple: false })
    expect(el._ripple?.enabled).toBe(false)

    await wrapper.setProps({ ripple: true })
    expect(el._ripple?.enabled).toBe(true)
  })

  it('should trigger ripple on mousedown', () => {
    vi.useFakeTimers()
    const wrapper = mount(testComponent)

    const mousedownEvent = new MouseEvent('mousedown')
    wrapper.element.dispatchEvent(mousedownEvent)

    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)

    const mouseupEvent = new MouseEvent('mouseup')
    wrapper.element.dispatchEvent(mouseupEvent)

    vi.runAllTimers()
    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)
  })

  it.each(['Enter', 'Space'] as const)('should trigger ripple on %s key press', key => {
    vi.useFakeTimers()
    const wrapper = mount(testComponent)

    const keydownEvent = new KeyboardEvent('keydown', { key })
    wrapper.element.dispatchEvent(keydownEvent)

    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)

    const keyupEvent = new KeyboardEvent('keyup')
    wrapper.element.dispatchEvent(keyupEvent)

    vi.runAllTimers()
    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)
  })

  it('should only ripple on one element', () => {
    vi.useFakeTimers()

    const wrapper = mount({
      directives: { Ripple },
      template: '<div v-ripple><div class="child" v-ripple></div></div>',
    })

    const child = wrapper.find('.child').element

    const mousedownEvent = new MouseEvent('mousedown', { detail: 1, bubbles: true })
    child.dispatchEvent(mousedownEvent)

    expect(wrapper.findAll('.v-ripple__container')).toHaveLength(1)

    const mouseupEvent = new MouseEvent('mouseup', { detail: 1, bubbles: true })
    child.dispatchEvent(mouseupEvent)

    vi.runAllTimers()
    expect(wrapper.findAll('.v-ripple__container')).toHaveLength(0)
  })

  it('should hide ripple on blur if keyboardRipple is true', () => {
    vi.useFakeTimers()
    const wrapper = mount(testComponent)
    const keydownEvent = new KeyboardEvent('keydown', { key: 'Enter' })
    wrapper.element.dispatchEvent(keydownEvent)

    expect(wrapper.find('.v-ripple__container').exists()).toBe(true)

    const blurEvent = new FocusEvent('blur')
    wrapper.element.dispatchEvent(blurEvent)

    vi.runAllTimers()
    expect(wrapper.find('.v-ripple__container').exists()).toBe(false)
  })
})
