<template>
  <v-line
    v-for="(axisConfig, i) in axisConfigs"
    :config="{ ...config, ...axisConfig }"
    :ref="(l: any) => lines[i] = l"
  />
  <v-circle
    v-if="debug"
    v-for="axisConfig in axisConfigs"
    :config="{ x: axisConfig.x, y: axisConfig.y, radius: 3, fill: '#000' }"
  />
</template>

<script lang="ts" setup>
import { computed, ComputedRef, ref } from "vue";
import { SnapInfo, useGlobalSnapInfos, useSnapResultInfo } from "../hook/use-snap";
import { useViewerTransform } from "../hook/use-viewer";
import { RectConfig } from "konva/lib/shapes/Rect";
import { themeColor } from "@/constant/help-style";
import { DC } from "@/deconstruction";
import { Line } from "konva/lib/shapes/Line";
import { useDashAnimation } from "../hook/use-animation";
import { useResize } from "../hook/use-event";
import { lineLen, Pos, vector, vector2IncludedAngle } from "@/utils/math";
import { flatPositions } from "@/utils/shared";
import { MathUtils } from "three";

const config: RectConfig = {
  dash: [10, 10],
  stroke: themeColor,
  strokeWidth: 1,
  listening: false,
};

type Axis = { point: Pos; direction: Pos; color?: string };

// const debug = import.meta.env.DEV;
const debug = false;
const size = useResize();

const viewerTransform = useViewerTransform();
const info = useSnapResultInfo();
const minOffset = 10;
const minAngle = MathUtils.degToRad(5);
let snapInfos: ComputedRef<SnapInfo[]>;
if (debug) {
  snapInfos = useGlobalSnapInfos();
}

const deduplication = (items: Axis[]) => {
  for (let i = 0; i < items.length; i++) {
    const direction = items[i].direction;
    const point = items[i].point;

    for (let j = i + 1; j < items.length; j++) {
      if (
        vector2IncludedAngle(items[j].direction, direction) < minAngle &&
        lineLen(items[j].point, point) < minOffset
      ) {
        items.splice(j--, 1);
      }
    }
  }
  return items;
};

const axiss = computed((): Axis[] => {
  const axiss = info.attractSnaps.map((snap) => ({
    point: snap.join,
    direction: snap.refDirection,
  }));

  if (debug && !axiss.length) {
    axiss.push(
      ...snapInfos.value.flatMap((info) => {
        return info.linkDirections.map((item) => ({
          point: info.point,
          direction: item,
        }));
      })
    );
  }
  return axiss;
});

const axisConfigs = computed(() => {
  if (!size.value) return;
  const len = Math.max(size.value.width, size.value.height);
  return axiss.value.map((item) => ({
    ...viewerTransform.value.point(item.point),
    points: flatPositions([
      vector(item.direction).multiplyScalar(-len),
      vector(item.direction).multiplyScalar(len),
    ]),
  }));
});

const lines = ref<DC<Line>[]>([]);
useDashAnimation(lines);
</script>
