<template>
  <div ref="" id="draggableElementView" class="draggable-box cursor-grab" :style="elementStyle"
    @mousedown.passive="handleStart" @touchstart.passive="handleStart" @click="handleClick">
    <slot></slot>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onUnmounted } from 'vue';
import { addResizeTimeOut, removeResizeTimeOut } from '@/utils';
export default defineComponent({
  name: 'PressDragComponent',
  emits: ['click'],
  props: {
    storageKey: {
      default: '',
    },
  },
  setup(props, { emit }) {
    const view = {
      offsetWidth: 50,
      offsetHeight: 50,
      innerWidth: 750,
      innerHeight: 1280,
    };
    const storageKeyVal = `_tem_drag_${props.storageKey}`;

    const initil = () => {
      const node = document.querySelector('#draggableElementView') as HTMLElement;
      view.offsetWidth = node.offsetWidth;
      view.offsetHeight = node.offsetHeight;

      view.innerWidth =
        window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
      view.innerHeight =
        window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    };
    addResizeTimeOut(initil);
    const isDragging = ref(false);
    const pressTimer = ref<number | null>(null);
    const startTime = ref(0);
    const elementStyle = ref<any>({
      userSelect: 'none',
      touchAction: 'none',
    });
    onMounted(() => {
      nextTick(() => {
        initil();
        // if (props.storageKey && props.storageKey.length > 0) {
        //   let storageVal: any = localStorage.getItem(storageKeyVal);
        //   if (storageVal && storageVal.length > 0) {
        //     storageVal = storageVal.split(',');
        //     setStyle(storageVal[0], storageVal[1]);
        //   }
        // }
      });
    });
    const handleStart = (e: MouseEvent | TouchEvent) => {
      e.preventDefault();
      startTime.value = Date.now();
      pressTimer.value = window.setTimeout(() => {
        isDragging.value = true;
        document.addEventListener('mousemove', handleDrag);
        document.addEventListener('touchmove', handleDrag, { passive: false });
        document.addEventListener('mouseup', handleEnd);
        document.addEventListener('touchend', handleEnd);
      }, 200);
    };

    const handleDrag = (e: MouseEvent | TouchEvent) => {
      if (!isDragging.value) return;
      e.preventDefault();
      const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
      const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY;
      let left = clientX - view.offsetWidth / 2;
      let top = clientY - view.offsetHeight / 2;

      left = left > view.innerWidth - view.offsetWidth ? view.innerWidth - view.offsetWidth : left;
      top = top > view.innerHeight - view.offsetHeight ? view.innerHeight - view.offsetHeight : top;
      setStyle(left, top);
    };
    const setStyle = (left: number, top: number) => {
      if (props.storageKey && props.storageKey.length > 0) {
        localStorage.setItem(storageKeyVal, [left, top].join(','));
      }

      // if (left > innerWidth - 90) {
      //   left = innerWidth - 90;
      // } else if (left < 30) {
      //   left = 30;
      // }
      // if (top > innerHeight - 90) {
      //   top = innerHeight - 90;
      // } else if (top < 30) {
      //   top = 30;
      // }

      left = (left / view.innerWidth) * 100;
      left = left < 0 ? 0 : left;

      top = (top / view.innerHeight) * 100;
      top = top < 0 ? 0 : top;
      elementStyle.value = {
        ...elementStyle.value,
        left: `${left}%`,
        top: `${top}%`,
      };
    };
    const handleEnd = () => {
      clearTimeout(pressTimer.value!);
      document.removeEventListener('mousemove', handleDrag);
      document.removeEventListener('touchmove', handleDrag);
      document.removeEventListener('mouseup', handleEnd);
      document.removeEventListener('touchend', handleEnd);
      isDragging.value = false;
    };
    const handleClick = (e: MouseEvent) => {
      if (Date.now() - startTime.value > 200) return;
      emit('click', e);
    };

    onUnmounted(() => {
      handleEnd();

      removeResizeTimeOut(initil);
    });
    return { elementStyle, handleStart, handleClick };
  },
});
</script>

<style scoped>
/* .draggable-box {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    transition: transform 0.1s, box-shadow 0.3s;
} */

.draggable-box:active {
  transform: scale(0.98);
}
</style>
