/**
 * Copyright (c) 2022 - present TinyVue Authors.
 * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
 *
 * Use of this source code is governed by an MIT-style license.
 *
 * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
 * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
 * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
 *
 */

/**
 * 触发事件,并返回是否在事件中执行了 preventDefault 方法,支持事件传递附加参数。
 *
 *     // 触发事件,返回 false 则退出
 *     if (!emitEvent(emit, 'before', 1)) {
 *       return
 *     }
 *
 *     // @before='before' 定义事件执行的函数
 *     function before(event, value) {
 *       // value: 1
 *       event.preventDefault() // 通知事件宿主停止执行
 *     }
 *
 * @param {Function} emit 触发事件的函数
 * @param {String} name 事件的名称
 * @returns {Boolean}
 */
export const emitEvent = (emit, name, ...args) => {
  let cancel = false

  if (typeof emit === 'function' && typeof name === 'string') {
    const event = document.createEvent('HTMLEvents')

    event.initEvent(name, false, true)
    event.preventDefault = () => {
      cancel = true
    }

    args.unshift(event)
    args.unshift(name)
    // eslint-disable-next-line prefer-spread
    emit.apply(null, args)
  }

  return !cancel
}

/**
 *  webComponent中,有些事件的target会代理到webComponent根元素上,导致无法获取正确的target
 *
 * @param event 浏览器事件
 * @returns 正确的target
 */
export const getActualTarget = (e) => {
  if (!e || !e.target) {
    return null
  }
  return e.target?.shadowRoot && e.composed ? e.composedPath()[0] || e.target : e.target
}

export const correctTarget = (event, target?: EventTarget) => {
  let newTarget

  if (event.target === null && target) {
    newTarget = target
  } else {
    const nodeList = event.composedPath()
    if (event.target !== nodeList[0]) {
      newTarget = nodeList[0]
    }
  }

  if (newTarget) {
    Object.defineProperty(event, 'target', {
      get() {
        return newTarget
      },
      enumerable: true,
      configurable: true
    })
  }
}