import { DesignComp } from "@/modules/editor/defines/DesignTemp/DesignComp";
import { css } from "@linaria/core";
import { defineComponent, onMounted, ref } from "vue";
import { string } from "vue-types";
import { useEditor } from "../../..";

export const Transfer = defineComponent({
  props: {
    compId: string().isRequired,
  },
  setup(props) {
    const { store, helper } = useEditor();
    const resizeRef = ref<HTMLElement>();
    const moveRef = ref<HTMLElement>();
    const start = {
      x: 0,
      y: 0,
      width: 0,
      height: 0,
      offsetX: 0,
      offsetY: 0,
    };

    const comp = store.designCompMap.get(props.compId) as DesignComp;
    let parentCompEl: HTMLElement;

    onMounted(() => {
      if (!resizeRef.value || !moveRef.value) return;
      resizeRef.value.addEventListener("mousedown", startDrag);
      moveRef.value.addEventListener("mousedown", startMove);
      const parentContentEl = getClosestParentWithClass(
        resizeRef.value,
        "view_content"
      );
      if (!parentContentEl) return;
      parentCompEl = parentContentEl;
    });

    function startMove(e: MouseEvent) {
      start.x = e.clientX;
      start.y = e.clientY;

      document.addEventListener("mousemove", move);
      document.addEventListener("mouseup", stopMove);
    }
    function move(e: MouseEvent) {
      const viewEl = parentCompEl.parentElement;
      if (!viewEl) return;
      start.offsetX = e.clientX - start.x;
      start.offsetY = e.clientY - start.y;

      viewEl.style.left = helper.designToNaturalSize(
        comp.value.position[0] + start.offsetX * 2
      );
      viewEl.style.top = helper.designToNaturalSize(
        comp.value.position[1] + start.offsetY * 2
      );
    }
    function stopMove(e: MouseEvent) {
      comp.value.position[0] += start.offsetX * 2;
      comp.value.position[1] += start.offsetY * 2;
      document.removeEventListener("mousemove", move);
      document.removeEventListener("mouseup", stopMove);
    }

    function startDrag(e: MouseEvent) {
      start.x = e.clientX;
      start.y = e.clientY;
      start.width = comp.layout.size?.[0] || 0;
      start.height = comp.layout.size?.[1] || 0;

      document.addEventListener("mousemove", drag);
      document.addEventListener("mouseup", stopDrag);
    }

    function drag(e: MouseEvent) {
      start.offsetX = e.clientX - start.x;
      start.offsetY = e.clientY - start.y;
      parentCompEl.style.width = helper.designToNaturalSize(
        start.width + start.offsetX * 2
      );
      parentCompEl.style.height = helper.designToNaturalSize(
        start.height + start.offsetY * 2
      );
    }

    function stopDrag() {
      comp.layout.size || (comp.layout.size = [0, 0]);
      comp.layout.size[0] = start.width + start.offsetX * 2;
      comp.layout.size[1] = start.height + start.offsetY * 2;
      document.removeEventListener("mousemove", drag);
      document.removeEventListener("mouseup", stopDrag);
    }

    return () => (
      <>
        <div ref={resizeRef} class={resizeStyle}></div>
        <div ref={moveRef} class={moveStyle}></div>
      </>
    );
  },
});

function getClosestParentWithClass(element: HTMLElement, className: string) {
  let parent = element.parentElement;

  while (parent) {
    if (parent.classList.contains(className)) {
      return parent;
    }
    parent = parent.parentElement;
  }

  return null;
}

const resizeStyle = css`
  position: absolute;
  bottom: 0;
  right: 0;
  width: 8px;
  height: 8px;
  border-bottom: 4px solid;
  border-right: 4px solid;
  border-color: @inf-primary-fade-color;
  cursor: nwse-resize;
  &:hover {
    border-color: @inf-primary-color;
  }
`;

const moveStyle = css`
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 40px;
  height: 4px;
  transform: translate(-50%, 50%);
  background-color: @inf-primary-color;
  border-radius: 4px;
  cursor: all-scroll;
  &:hover {
    border-color: #fff;
    box-shadow: 0 0 3px 2px rgba(0, 0, 0, 0.5);
    outline: 2px solid #fff;
  }
`;
