import type { Directive } from "vue";

interface BindValue {
  moveElement?: ({ left, top }: { left: number; top: number }) => void;
  moveStop?: ({ left, top }: { left: number; top: number }) => void;
  moveStart?: (e: MouseEvent) => void;
  emitOriginLeftTop?: boolean;
}

export const vEleMoveDirective: Directive<HTMLElement, BindValue> = {
  mounted(el, { value, modifiers }) {
    let [_x, _y] = [0, 0];
    let [ox, oy] = [0, 0];
    // 只允许鼠标左键触发
    const moveHandle = (e: MouseEvent) => {
      if (e.button !== 0) return;
      if (modifiers.prevent) {
        e.preventDefault();
      }
      if (modifiers.stop) {
        e.stopPropagation();
      }

      let left = 0;
      let top = 0;

      if (value.emitOriginLeftTop) {
        left = ox + e.pageX - _x;
        top = oy + e.pageY - _y;
      } else {
        left = e.pageX - _x;
        top = e.pageY - _y;
      }

      value.moveElement && value.moveElement({ left, top });
    };

    const upHandle = (e: MouseEvent) => {
      if (e.button !== 0) return;
      if (modifiers.prevent) {
        e.preventDefault();
      }
      if (modifiers.stop) {
        e.stopPropagation();
      }

      let left = 0;
      let top = 0;

      if (value.emitOriginLeftTop) {
        left = ox + e.pageX - _x;
        top = oy + e.pageY - _y;
      } else {
        left = e.pageX - _x;
        top = e.pageY - _y;
      }

      value.moveStop && value.moveStop({ left, top });
      document.removeEventListener("mousemove", moveHandle);
      document.removeEventListener("mouseup", upHandle);
    };

    el.addEventListener("mousedown", (e: MouseEvent) => {
      if (e.button !== 0) return;
      if (modifiers.prevent) {
        e.preventDefault();
      }
      if (modifiers.stop) {
        e.stopPropagation();
      }
      _x = e.pageX;
      _y = e.pageY;
      ox = el.offsetLeft;
      oy = el.offsetTop;
      value.moveStart && value.moveStart(e);

      document.addEventListener("mousemove", moveHandle);
      document.addEventListener("mouseup", upHandle);
    });
  },
};
