import { ObjectDirective } from 'vue';
import { throttle } from 'lodash-es';

export const bindMoveTool = (el: HTMLElement, binding) => {
  const initScale = binding.value ? binding.value : 1;
  const targetkey = binding.arg ? Number(binding.arg) : 0;
  const transInfo = {
    zoom: initScale,
    toMove: false,
    toScale: false,
    transOriginX: 50,
    transOriginY: 50,
    translateX: 0,
    translateY: 0,
    distance: 1,
    mouseInit: { x: 0, y: 0 },
    curMousePos: { x: 0, y: 0 },
  };

  const setBgStyle = () => {
    el.setAttribute(
      'style',
      `transform-origin: ${transInfo.transOriginX}% ${transInfo.transOriginY}%; transform: translate(${transInfo.translateX}px, ${transInfo.translateY}px)  scale(${transInfo.zoom})`,
    );
  };

  const calcTransOrigin = (mouseX: number, mouseY: number) => {
    const mapBgInfo = el.getBoundingClientRect();
    if (transInfo.zoom !== initScale) {
      transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
      transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
    }
    transInfo.transOriginX = ((mouseX - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
    transInfo.transOriginY = ((mouseY - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
    transInfo.mouseInit = { x: mouseX, y: mouseY };
  };

  const scaleProcess = (e) => {
    if (e.wheelDelta > 0) {
      const newZoom = transInfo.zoom + 0.2;
      if (newZoom <= 10) {
        calcTransOrigin(e.clientX, e.clientY);
        transInfo.zoom = newZoom;
      }
    } else if (e.wheelDelta < 0) {
      const newZoom = transInfo.zoom - 0.2;
      if (newZoom >= 0.2) {
        calcTransOrigin(e.clientX, e.clientY);
        transInfo.zoom = newZoom;
      }
    }
    setBgStyle();
  };

  const throttleScale = throttle(scaleProcess, 200);

  const handleScale = (e) => {
    if (e.ctrlKey) {
      e.preventDefault();
      throttleScale(e);
      // if (e.wheelDelta > 0) {
      //   const newZoom = transInfo.zoom + 0.2;
      //   if (newZoom <= 10) {
      //     calcTransOrigin(e.clientX, e.clientY);
      //     transInfo.zoom = newZoom;
      //   }
      // } else if (e.wheelDelta < 0) {
      //   const newZoom = transInfo.zoom - 0.2;
      //   if (newZoom >= 0.2) {
      //     calcTransOrigin(e.clientX, e.clientY);
      //     transInfo.zoom = newZoom;
      //   }
      // }
      // setBgStyle();
    }
  };

  const handleMouseDown = (e) => {
    if (e.button === targetkey) {
      transInfo.toMove = true;
      transInfo.curMousePos = { x: e.clientX, y: e.clientY };
    }
  };

  const handleMouseMove = (e) => {
    if (transInfo.toMove) {
      transInfo.translateX += e.clientX - transInfo.curMousePos.x;
      transInfo.translateY += e.clientY - transInfo.curMousePos.y;
      transInfo.mouseInit = {
        x: transInfo.mouseInit.x + (e.clientX - transInfo.curMousePos.x),
        y: transInfo.mouseInit.y + (e.clientY - transInfo.curMousePos.y),
      };
    }
    transInfo.curMousePos = { x: e.clientX, y: e.clientY };
    setBgStyle();
  };

  const handleMouseUp = () => {
    transInfo.toMove = false;
    transInfo.curMousePos = { x: 0, y: 0 };
  };

  // const calcMobileTransOrigin = (mouseX: number, mouseY: number) => {
  //   const mapBgInfo = el.getBoundingClientRect();
  //   if (transInfo.zoom !== initScale) {
  //     transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
  //     transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
  //   }
  //   transInfo.transOriginX = ((mouseX - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
  //   transInfo.transOriginY = (1 - (mouseY - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
  //   transInfo.mouseInit = { x: mouseX, y: mouseY };
  // };

  // const handleTouchStart = (e) => {
  //   const touches = e.touches;
  //   if (touches.length == 1) {
  //     transInfo.toMove = true;
  //     transInfo.toScale = false;
  //     transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
  //   } else if (touches.length == 2) {
  //     transInfo.toMove = false;
  //     transInfo.toScale = true;
  //     // 计算中点
  //     const midX = (touches[0].pageY + touches[1].pageY) / 2;
  //     const midY = (touches[0].pageX + touches[1].pageX) / 2;
  //     calcMobileTransOrigin(midX, midY);
  //     // 计算距离
  //     const disX = Math.abs(touches[0].pageY - touches[1].pageY);
  //     const disY = Math.abs(touches[0].pageX - touches[1].pageX);
  //     transInfo.distance = Math.sqrt(disX * disX + disY * disY);
  //   }
  // };

  // const handleTouchMove = (e) => {
  //   const touches = e.touches;
  //   if (touches.length == 1 && transInfo.toMove) {
  //     transInfo.toMove = true;
  //     transInfo.toScale = false;
  //     transInfo.translateX += touches[0].pageY - transInfo.curMousePos.x;
  //     transInfo.translateY -= touches[0].pageX - transInfo.curMousePos.y;
  //     transInfo.mouseInit = {
  //       x: transInfo.mouseInit.x + (touches[0].pageY - transInfo.curMousePos.x),
  //       y: transInfo.mouseInit.y - (touches[0].pageX - transInfo.curMousePos.y),
  //     };
  //     transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
  //     setBgStyle();
  //   } else if (touches.length == 2 && transInfo.toScale) {
  //     e.preventDefault();
  //     transInfo.toMove = false;
  //     transInfo.toScale = true;
  //     // 计算距离
  //     const disX = Math.abs(touches[0].pageY - touches[1].pageY);
  //     const disY = Math.abs(touches[0].pageX - touches[1].pageX);
  //     const curDistance = Math.sqrt(disX * disX + disY * disY);
  //     transInfo.zoom = transInfo.zoom * (curDistance / transInfo.distance);
  //     setBgStyle();
  //     transInfo.distance = curDistance;
  //   }
  // };

  // const handleTouchEnd = () => {
  //   transInfo.toMove = false;
  //   transInfo.toScale = false;
  //   transInfo.distance = 1;
  //   transInfo.curMousePos = { x: 0, y: 0 };
  // };

  setBgStyle();
  el.addEventListener('mousewheel', handleScale);
  el.addEventListener('mousedown', handleMouseDown);
  el.addEventListener('mousemove', handleMouseMove);
  el.addEventListener('mouseup', handleMouseUp);
};

export const moveable: ObjectDirective = {
  mounted(el: HTMLElement, binding) {
    bindMoveTool(el, binding);
  },
};
