import { registerAsyncHelper } from '@ember/test'
import { run } from '@ember/runloop'
import $ from 'jquery'

// integration helpers
function focus(el) {
  if (!el) {
    return
  }
  let $el = $(el)
  if ($el.is(':input, [contenteditable=true]')) {
    let type = $el.prop('type')
    if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
      run(null, function () {
        // Firefox does not trigger the `focusin` event if the window
        // does not have focus. If the document doesn't have focus just
        // use trigger('focusin') instead.

        if (!document.hasFocus || document.hasFocus()) {
          el.focus()
        } else {
          $el.trigger('focusin')
        }
      })
    }
  }
}

export function nativeClick(selector, options = {}) {
  let mousedown = new window.Event('mousedown', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  let mouseup = new window.Event('mouseup', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  let click = new window.Event('click', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  Object.keys(options).forEach((key) => {
    mousedown[key] = options[key]
    mouseup[key] = options[key]
    click[key] = options[key]
  })

  let element = document.querySelector(selector)
  run(() => element.dispatchEvent(mousedown))
  focus(element)
  run(() => element.dispatchEvent(mouseup))
  run(() => element.dispatchEvent(click))
}

export function nativeHover(selector, options = {}) {
  let mouseenter = new window.Event('mouseenter', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  Object.keys(options).forEach((key) => {
    mouseenter[key] = options[key]
  })

  let element = document.querySelector(selector)
  focus(element)
  run(() => element.dispatchEvent(mouseenter))
}

export function hoverTrigger(scope, options = {}) {
  let selector = '.ember-basic-dropdown-trigger'
  if (scope) {
    selector = scope + ' ' + selector
  }
  nativeHover(selector, options)
}

export function clickTrigger(scope, options = {}) {
  let selector = '.ember-basic-dropdown-trigger'
  if (scope) {
    selector = scope + ' ' + selector
  }
  nativeClick(selector, options)
}

export function tapTrigger(scope, options = {}) {
  let selector = '.ember-basic-dropdown-trigger'
  if (scope) {
    selector = scope + ' ' + selector
  }
  let touchStartEvent = new window.Event('touchstart', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  Object.keys(options).forEach((key) => (touchStartEvent[key] = options[key]))
  run(() => document.querySelector(selector).dispatchEvent(touchStartEvent))
  let touchEndEvent = new window.Event('touchend', {
    bubbles: true,
    cancelable: true,
    view: window,
  })
  Object.keys(options).forEach((key) => (touchEndEvent[key] = options[key]))
  run(() => document.querySelector(selector).dispatchEvent(touchEndEvent))
}

export function fireKeydown(selector, k) {
  let oEvent = document.createEvent('Events')
  oEvent.initEvent('keydown', true, true)
  $.extend(oEvent, {
    view: window,
    ctrlKey: false,
    altKey: false,
    shiftKey: false,
    metaKey: false,
    keyCode: k,
    charCode: k,
  })
  run(() => document.querySelector(selector).dispatchEvent(oEvent))
}

// acceptance helpers
export default function () {
  registerAsyncHelper('clickDropdown', function (app, cssPath, options = {}) {
    clickTrigger(cssPath, options)
  })

  registerAsyncHelper('tapDropdown', function (app, cssPath, options = {}) {
    tapTrigger(cssPath, options)
  })
}
