<!-- eslint-disable vue/no-unused-vars -->
<!-- eslint-disable vue/valid-v-for -->
<template>
  <div ref="wrapRef" class="svg-wrap" @mousemove="handleMouseMove">
    <svg
      version="1.1"
      baseProfile="full"
      xmlns="http://www.w3.org/2000/svg"
      xmlns:xlink="http://www.w3.org/1999/xlink"
      xmlns:ev="http://www.w3.org/2001/xml-events"
      :width="wrapSize.width"
      :height="wrapSize.height"
    >
      <SvgRect
        v-for="i in children"
        :key="i.id"
        v-bind="i"
        :draggingId="draggingId"
        :mousePos="curPos"
        @startLine="startLine"
        @startDrag="startDrag"
        @updatePos="updatePos"
      />

      <line v-if="lineStartPoint" v-bind="dashLineAttr"></line>
    </svg>
  </div>
</template>

<script setup>
import { reactive, ref, onBeforeUnmount, onMounted, computed } from "vue";
import SvgRect from "./components/svgRect.vue";
import { findFromArray, getPosFromEvent } from "./utils/index";

const wrapRef = ref(null);
const childrenRefs = ref(null);
let curPos = ref({ x: 0, y: 0 });
const wrapSize = reactive({ width: 0, height: 0 });
const draggingId = ref(0);
const lineStartPoint = ref(null);
const children = ref([
  { id: 1, pos: { x: 10, y: 10 }, size: { width: 100, height: 100 } },
  { id: 2, pos: { x: 20, y: 20 }, size: { width: 100, height: 100 } },
  { id: 3, pos: { x: 30, y: 30 }, size: { width: 100, height: 100 } },
]);

const dashLineAttr = computed(() => {
  if (lineStartPoint.value) {
    return {
      x1: lineStartPoint.value?.cx,
      y1: lineStartPoint.value?.cy,
      x2: curPos.value.x,
      y2: curPos.value.y,
      stroke: "black",
      "stroke-dasharray": "3 4",
      "stroke-width": "2",
    };
  }
  return {};
});

function startDrag({ id, event }) {
  draggingId.value = id;
  lineStartPoint.value = null;
  curPos.value = getPosFromEvent(event);
  const { index, result } = findFromArray(children.value, (i) => i.id === id);
  children.value.splice(index, 1);
  children.value.push(result);
}

function startLine({ id, point }) {
  draggingId.value = 0;
  lineStartPoint.value = point;
}

function updatePos({ id, pos }) {
  const { result } = findFromArray(children.value, (i) => i.id === id);
  result.pos = pos;
}

function handleMouseMove(e) {
  curPos.value = getPosFromEvent(e);
}

function handleMouseUp() {
  draggingId.value = 0;
  lineStartPoint.value = null;
}

function initSvgSize() {
  // 避免因为转rem时有小数误差导致得滚动条
  wrapSize.width = wrapRef.value.offsetWidth - 1;
  wrapSize.height = wrapRef.value.offsetHeight - 1;
}

window.addEventListener("mouseup", handleMouseUp);
window.addEventListener("resize", initSvgSize);

onMounted(() => {
  initSvgSize();
});

onBeforeUnmount(() => {
  window.removeEventListener("mouseup", handleMouseUp);
  window.removeEventListener("resize", initSvgSize);
});
</script>

<style lang="less" scoped>
.svg-wrap {
  min-height: 400px;
  background-color: blue;
  background-image: linear-gradient(
      transparent 0px,
      transparent 2px,
      #fff 2px,
      #fff 15px
    ),
    linear-gradient(90deg, #ccc 0px, #ccc 2px, #fff 2px, #fff 15px);
  background-size: 15px 15px, 15px 15px;
  position: relative;
  svg {
    display: block;
  }
}
</style>
