<template>
  <g class="lines-wrap">
    <marker
      id="markerArrow"
      markerUnits="strokeWidth"
      markerWidth="5"
      markerHeight="4"
      refX="6"
      refY="2"
      orient="auto"
    >
      <path d="M 0 0 L 5 2 L 0 4 z" class="trangle" />
    </marker>
    <path
      v-for="i in linesAttr"
      :key="i.id"
      v-bind="i"
      class="line"
      marker-end="url(#markerArrow)"
    />
  </g>
</template>

<script setup>
import { computed } from "vue";
import { countPointByPos } from "../utils/index";
const props = defineProps(["nodes", "lines"]);

function getTransitPoint(pos, point) {
  const transitSpace = 20;
  switch (pos) {
    case "left":
      return {
        cx: point.cx - transitSpace,
        cy: point.cy,
      };
    case "top":
      return {
        cx: point.cx,
        cy: point.cy - transitSpace,
      };
    case "right":
      return {
        cx: point.cx + transitSpace,
        cy: point.cy,
      };
    case "bottom":
      return {
        cx: point.cx,
        cy: point.cy + transitSpace,
      };
    default:
      break;
  }
}

function getAnchor(start, end) {
  const { point: startPoint, node: startNode, pos: startPos } = start;
  const { point: endPoint, node: endNode, pos: endPos } = end;

  let p1, p2;
  const space = 20;
  if (["left", "right"].includes(startPos)) {
    p1 = {
      cx: startPoint.cx,
      cy:
        startPoint.cy +
        (endPoint.cy > startPoint.cy
          ? startNode.size.height / 2 + 20
          : -(startNode.size.height / 2 + 20)),
    };
  } else {
    p1 = {
      cx:
        startPoint.cx +
        (endPoint.cx > startPoint.cx
          ? startNode.size.width / 2 + 20
          : -(startNode.size.width / 2 + 20)),
      cy: startPoint.cy,
    };
  }
  if (["left", "right"].includes(endPos)) {
    p2 = {
      cx: endPoint.cx,
      cy:
        endPoint.cy +
        (endPoint.cy > startPoint.cy
          ? -(endNode.size.height / 2 + 20)
          : endNode.size.height / 2 + 20),
    };
  } else {
    p2 = {
      cx:
        endPoint.cx +
        (endPoint.cx > startPoint.cx
          ? -(endNode.size.width / 2 + 20)
          : endNode.size.width / 2 + 20),
      cy: endPoint.cy,
    };
  }

  return [p1, p2];
}

function getCenterPoint(start, end) {
  const { point: startPoint, node: startNode, pos: startPos } = start;
  const { point: endPoint, node: endNode, pos: endPos } = end;
  // const [p1, p2] = getAnchor(start, end);
  // const points = [
  //   startPoint,
  //   p1,
  //   {
  //     cx: p1.cx,
  //     cy: p2.cy,
  //   },
  //   p2,
  //   endPoint,
  // ];

  // points.forEach((p, index) => {
  //   if (index >= 2) {
  //     const preP1 = points[index - 1];
  //     const preP2 = points[index - 2];
  //     if (preP1.cx === preP2.cx && preP1.cx === p.cx) {
  //       preP2.cy = preP1.cy = Math.min(preP2.cy, preP1.cy, p.cy);
  //     }
  //     if (preP1.cy === preP2.cy && preP1.cy === p.cy) {
  //       preP2.cx = preP1.cx = Math.min(preP2.cx, preP1.cx, p.cx);
  //     }
  //   }
  // });
  // return points;
  return [startPoint, { cx: startPoint.cx, cy: endPoint.cy }, endPoint];
  // const points = [];
  // let p1, p2;
  // if (["left", "right"].includes(startNode.pos)) {
  //   p1 = {
  //     cx: start.cx,
  //     cy: end.cy,
  //   };
  // } else {
  //   p1 = {
  //     cx: end.cx,
  //     cy: start.cy,
  //   };
  // }
  // if (["left", "right"].includes(endNode.pos)) {
  //   p2 = {
  //     cx: end.cx,
  //     cy: p1.cy,
  //   };
  // } else {
  //   p2 = {
  //     cx: p1.cx,
  //     cy: end.cy,
  //   };
  // }
  // if (start.cx < end.cx && endNode.pos === "right") {
  //   const topSpace = Math.min(startNode.node.pos.y, endNode.node.pos.y) - 20;
  //   return [
  //     {
  //       cx: start.cx,
  //       cy: startNode.node.pos.cy + (end.cy - start.cy) / 2,
  //     },
  //     {
  //       cx: end.cx,
  //       cy: start.cy + (end.cy - start.cy) / 2,
  //     },
  //   ];
  // }
  // if (start.cy > end.cy) {
  //   const endWidth = endNode.size.width / 2 + 20;
  //   return [
  //     {
  //       cx: start.cx - endWidth,
  //       cy: end.cy,
  //     },
  //     {
  //       cx: end.cx - endWidth,
  //       cy: end.cy,
  //     },
  //   ];
  // }
  // return [p1, p2];
  // return [
  //   {
  //     cx: start.cx,
  //     cy: end.cy,
  //   },
  //   {
  //     cx: start.cx,
  //     cy: end.cy,
  //   },
  // ];
}

const linesAttr = computed(() =>
  props.lines.map((line) => {
    const { targetId: startTargetId, pos: startPos } = line.start;
    const { targetId: endTargetId, pos: endPos } = line.end;
    const startNode = props.nodes.find((i) => i.id === startTargetId);
    const endNode = props.nodes.find((i) => i.id === endTargetId);
    const startPoint = countPointByPos(startPos, startNode.pos, startNode.size);
    const endPoint = countPointByPos(endPos, endNode.pos, endNode.size);

    const startTransitPoint = getTransitPoint(startPos, startPoint);
    const endTransitPoint = getTransitPoint(endPos, endPoint);
    const centerPoints = getCenterPoint(
      { node: startNode, pos: startPos, point: startTransitPoint },
      { node: endNode, pos: endPos, point: endTransitPoint }
    );

    return {
      id: `${startTargetId}-${startPos}-${endTargetId}-${endPos}`,
      d: [
        `M${startPoint.cx} ${startPoint.cy}`,
        ...centerPoints.map((i) => `L${i.cx} ${i.cy}`),
        `L${endPoint.cx} ${endPoint.cy}`,
      ].join(" "),
    };
    // return {
    //   id: `${startTargetId}-${startPos}-${endTargetId}-${endPos}`,
    //   x1: startPoint.cx,
    //   y1: startPoint.cy,
    //   x2: endPoint.cx,
    //   y2: endPoint.cy,
    // };
  })
);
</script>

<style lang="less" scoped>
.lines-wrap {
  .line {
    stroke: #5ba8ff;
    stroke-width: 2;
    fill: transparent;
  }

  .trangle {
    stroke: #5ba8ff;
    fill: #5ba8ff;
  }
}
</style>
