import type { ObjectDirective } from 'vue'

export const clickOutside = {
  beforeMount(element, binding) {
    element.setDragging = () => {
      !element.hasAttribute('data-dragging') &&
        element.setAttribute('data-dragging', true)
    }
    element.clearDragging = () => {
      element.removeAttribute('data-dragging')
    }
    element.clickOutsideEvent = (e: MouseEvent) => {
      if (
        !(
          element === e.target ||
          element.contains(e.target) ||
          element.hasAttribute('data-dragging')
        )
      ) {
        binding.value(e)
      }
    }

    document.addEventListener('touchstart', element.clearDragging)
    document.addEventListener('touchmove', element.setDragging)
    document.addEventListener('touchend', element.clickOutsideEvent)
    document.addEventListener('mousedown', element.clearDragging)
    document.addEventListener('mousemove', element.setDragging)
    document.addEventListener('mouseup', element.clickOutsideEvent)
  },
  unmounted(element) {
    document.removeEventListener('touchstart', element.clearDragging)
    document.removeEventListener('touchmove', element.setDragging)
    document.removeEventListener('touchend', element.clickOutsideEvent)
    document.removeEventListener('mousedown', element.clearDragging)
    document.removeEventListener('mousemove', element.setDragging)
    document.removeEventListener('mouseup', element.clickOutsideEvent)
  },
} satisfies ObjectDirective
