// src/directives/draggable.ts
import { Directive, DirectiveBinding } from "vue";

interface ElType extends HTMLElement {
  parentNode: any;
}
interface bindingProps {
  /**
   * @description 按钮唯一标识
   */
  id: string;
  /**
   * @description 初始位置[left, top]，百分数
   */
  originLeft?: number;
  originTop?: number;
  /**
   * @description 吸附左边界距离，默认为0，支持传入数字或百分比，如：10，10%，-50%，以其自身宽度为标准
   */
  left?: number | string;
  /**
   * @description 吸附右边界距离，默认为0，支持传入数字或百分比，如：10，10%，-50%，以其自身宽度为标准
   */
  right?: number | string;
  /**
   * @description 顶部最小距离，默认为0，支持传入数字，如：10
   */
  top?: number;
  /**
   * @description 底部最小距离，默认为0，支持传入数字，如：10
   */
  bottom?: number;
  /**
   * @description 吸附方向，可选"left", "right"，默认为["left", "right"]
   */
  directions?: string[];
  /**
   * @description 位置变化回调
   */
  change?: any;
  /**
   * @description 点击回调
   */
  click?: any;
}

const draggable: Directive = {
  mounted(el: ElType, binding: DirectiveBinding) {
    console.log("binding  : >>", el, binding, el.style.width, el.clientWidth, el.clientWidth, el.clientHeight);
    console.log('getFixed(binding, "top", el.clientHeight :>> ', getFixed(binding, "top", el.clientHeight));
    let bindingValue = binding.value as bindingProps;
    const fixedTop = getFixed(binding, "top", el.clientHeight);
    const fixedBottom = getFixed(binding, "bottom", el.clientHeight);
    const fixedLeft = getFixed(binding, "left", el.clientWidth);
    const fixedRight = getFixed(binding, "right", el.clientWidth);
    const directions = bindingValue?.directions ?? ["left", "right"];
    let winW = window.innerWidth;
    let winH = window.innerHeight;
    const halfContW = el.clientWidth;
    const halfContH = el.clientHeight;

    let disX: any, disY: any, moveX: any, moveY: any, startX: any, startY: any;
    let isDowning = false;

    let _originLeft = bindingValue?.originLeft ?? 0;
    let _originTop = bindingValue?.originTop ?? 0;
    // 百分比转换像素
    moveX = (Number(_originLeft) / 100) * winW;
    moveY = (Number(_originTop) / 100) * winH;

    console.log("origin moveX :>> ", moveX, moveY);
    gotoAdsorb();

    // Add window resize event listener
    window.addEventListener("resize", onWindowResize);

    function onWindowResize(e: any) {
      // Update the window dimensions and other necessary variables
      winW = window.innerWidth;
      winH = window.innerHeight;

      gotoAdsorb(e);
    }

    /**
     * @description 吸附侧栏
     * @param e 鼠标事件
     */
    function gotoAdsorb(e?: any) {
      // 限制吸附距离
      let L = 0 + fixedLeft;
      let R = winW - halfContW - fixedRight;

      console.log("R :>> ", R, directions, moveX, winW, winW / 2, moveX > winW / 2);
      console.log("L :>> ", L, directions, fixedBottom, fixedTop, fixedLeft, fixedRight);
      if (moveX > winW / 2) {
        moveX = directions.includes("right") ? R : L;
      } else {
        moveX = directions.includes("left") ? L : R;
      }
      if (moveY < fixedTop && fixedTop > 0) {
        moveY = fixedTop;
      } else if (moveY > winH - halfContH - fixedBottom && fixedBottom > 0) {
        moveY = winH - halfContH - fixedBottom;
      }
      console.log("moveX :>> ", moveX, moveY);
      el.style.left = moveX + "px";
      el.style.top = moveY + "px";
      el.style.transition = "all 0.5s";
      e && e.stopPropagation();
      document.onmousedown = document.onmousemove = document.onmouseup = null;
    }

    // 添加鼠标悬停事件监听器
    el.onmouseover = () => {
      // isHovering = true;
      // 限制吸附距离
      if (el.offsetLeft > winW - halfContW) {
        el.style.left = winW - halfContW + "px";
      }
      if (el.offsetLeft < 0) {
        el.style.left = 0 + "px";
      }
    };

    el.onmouseout = (e: any) => {
      // isHovering = false;
      !isDowning && gotoAdsorb(e);
    };
    el.onmousedown = (e: any) => {
      isDowning = true;
      //手指按下时的坐标
      startX = e.clientX;
      startY = e.clientY;
      disX = e.pageX - el.offsetLeft;
      disY = e.pageY - el.offsetTop;
      e.stopPropagation();

      document.onmousemove = (e: any) => {
        let moveStartX = e.pageX,
          moveStartY = e.pageY,
          clientWidth = document.documentElement.clientWidth,
          clientHeight = document.documentElement.clientHeight;
        let L, T, startXEnd, startYEnd;
        L = moveStartX - disX;
        T = moveStartY - disY;
        //移动时 当前位置与起始位置之间的差值

        startXEnd = moveStartX - startX;
        startYEnd = moveStartY - startY;
        if (L < 0) {
          //限制拖拽的X范围，不能拖出屏幕
          L = 0;
        } else if (L > clientWidth - el.clientWidth) {
          L = clientWidth - el.clientWidth;
        }
        if (T < 0) {
          //限制拖拽的Y范围，不能拖出屏幕
          T = 0;
        } else if (T > clientHeight - el.clientHeight) {
          T = clientHeight - el.clientHeight;
        }
        moveX = L;
        moveY = T;
        el.style.left = moveX + "px";
        el.style.top = moveY + "px";
        el.style.transition = "none";
        e.stopPropagation();
      };
      document.onmouseup = (e: any) => {
        isDowning = false;
        // 检查是否为点击操作
        console.log("onmouseup ifclick :>> ", startX === e.clientX && startY === e.clientY);
        if (startX === e.clientX && startY === e.clientY) {
          // 如果是点击，则取消拖动
          document.onmousedown = document.onmousemove = document.onmouseup = null;
          bindingValue.click && bindingValue.click();
          return;
        }
        gotoAdsorb(e);

        // 数值转换百分比
        let _left = moveX > winW / 2 ? 100 : 0;
        let _top = Math.round((moveY / winH) * 100);

        bindingValue.change && bindingValue.change(bindingValue.id, _left, _top);
      };
    };
  }
};

function getFixed(data: any, attr: string, length: number) {
  console.log("data :>> ", data);
  if (typeof data.value === "object" && Object.keys(data?.value).includes(attr)) {
    let res = data.value[attr];
    if (String(res).indexOf("%") > -1) {
      res = (res.replace("%", "") / 100) * length;
    }
    return res;
  }
  return 0;
}

export default draggable;
