<template>
  <div
      class="cover-layout"
      @click="clickHandler"
      @mousedown.stop.prevent="downHandler"
      @touchstart.stop.prevent="downHandler"
      :class="{ move: move }"
      :style="style"
      ref="dom"
  >
    <slot />
  </div>
</template>

<script setup lang="ts">
import {computed, onMounted, onUnmounted, ref, watch} from 'vue'
import {Pos, Pos3D} from '@/sdk'
import {useSDK} from '@/hook'
import { getPostionByTarget} from '@/components/base/utils'

const props = defineProps<{
  pos: Pos3D
}>()
const emit = defineEmits<{
  (m: 'changePos', pos: Pos3D): void
  (m: 'focus'): void
  (m: 'blur'): void
}>()
const sdk = useSDK()
const dom = ref<HTMLElement>()

const screen = ref<Pos>(null)
const style = computed(
  () =>
    screen.value && {
      left: screen.value.x + 'px',
      top: screen.value.y + 'px'
    }
)
const updatePos = () => {
  if (props.pos) {
    const data = sdk.scene.getScreenByPoint(props.pos)
    screen.value = data.trueSide ? data.pos : null
  }
}

sdk.scene.on('posChange', updatePos)
watch(props, updatePos)
updatePos()

const move = ref(false)
const downHandler = (sev: MouseEvent | TouchEvent) => {
  const el = sev.target as HTMLElement
  const mountEl = document.documentElement
  const preset = {
    x: el.offsetWidth / 2,
    y: el.offsetHeight
  }
  if (sev instanceof TouchEvent) {
    const pos = getPostionByTarget(el, document.querySelector("#app") as HTMLElement);
    preset.x = preset.x - (sev.touches[0].pageX  - (pos.x - preset.x))
    preset.y = preset.y - (sev.touches[0].pageY  - (pos.y - preset.y))
    console.log(
      pos,
      sev.touches[0].clientX,
    sev.touches[0].clientY,
      preset
    )
  } else {
    preset.x -= sev.offsetX
    preset.y -= sev.offsetY
  }

  const moveHandler = (ev: MouseEvent | TouchEvent) => {
    move.value = true
    const pos = sdk.scene.getPointByScreen({
      x: (ev instanceof TouchEvent ? ev.touches[0].pageX : ev.pageX) + preset.x,
      y: (ev instanceof TouchEvent ? ev.touches[0].pageY : ev.pageY) + preset.y,
      inDrag: true
    })
    if (pos.position) {
      emit('changePos', pos.position);
    }
  }
  const upHandler = (ev: MouseEvent) => {
    mountEl.removeEventListener('mousemove', moveHandler)
    mountEl.removeEventListener('mouseup', upHandler)
    mountEl.removeEventListener('touchmove', moveHandler)
    mountEl.removeEventListener('touchend', upHandler)
    move.value = false
  }

  mountEl.addEventListener('mousemove', moveHandler)
  mountEl.addEventListener('mouseup', upHandler)
  mountEl.addEventListener('touchmove', moveHandler)
  mountEl.addEventListener('touchend', upHandler)
}

const clickHandler = ev => {
  emit("focus")

  const handler = (ev: MouseEvent) => {
    if (!dom.value.contains(ev.target as HTMLElement) && ev.target !== dom.value) {
      emit("blur")
      document.documentElement.removeEventListener("click", handler)
    }
  }
  document.documentElement.addEventListener("click", handler, { passive: true })
}

onUnmounted(() => {
  emit("blur")
})
</script>

<style scoped lang="scss">
.cover-layout {
  position: absolute;
  z-index: 1;
  transform: translate(-50%, -100%);
  cursor: move;
}

.move {
  pointer-events: none;
}
</style>
