<template>
  <v-group ref="shape">
    <v-line
      name="repShape"
      :config="{
        ...data,
        closed: true,
        zIndex: undefined,
        points: flatPositions(data.points),
        opacity: addMode ? 0.3 : data.opacity,
      }"
    >
    </v-line>
    <Point
      v-for="(p, ndx) in data.points"
      :id="data.id + ndx"
      :shapeId="data.id"
      :position="p"
      :size="data.strokeWidth + 6"
      :color="data.stroke"
      @update:position="(p) => emit('update:position', { ndx, val: p })"
      @dragend="endHandler()"
      @dragstart="startHandler(ndx)"
    />
  </v-group>
</template>

<script lang="ts" setup>
import Point from "../share/point.vue";
import { defaultStyle, PolygonData } from "./index.ts";
import { flatPositions, rangMod } from "@/utils/shared.ts";
import { computed, ref } from "vue";
import { DC } from "@/deconstruction.js";
import { Line } from "konva/lib/shapes/Line";
import { Pos } from "@/utils/math.ts";
import { useCustomSnapInfos } from "@/core/hook/use-snap.ts";
import { ComponentSnapInfo } from "../index.ts";
import { generateSnapInfos } from "../util.ts";
const props = defineProps<{ data: PolygonData; addMode?: boolean }>();
const emit = defineEmits<{
  (e: "update:position", data: { ndx: number; val: Pos }): void;
  (e: "update"): void;
}>();

const data = computed(() => ({ ...defaultStyle, ...props.data }));
const shape = ref<DC<Line>>();
defineExpose({
  get shape() {
    return shape.value;
  },
});

const infos = useCustomSnapInfos();
const addedInfos = [] as ComponentSnapInfo[];
const clearInfos = () => {
  addedInfos.forEach(infos.remove);
};

const startHandler = (ndx: number) => {
  clearInfos();
  const len = props.data.points.length;
  const geos = [props.data.points.slice(0, ndx), props.data.points.slice(ndx + 1, len)];
  if (len > 2) {
    geos.push([
      props.data.points[rangMod(ndx - 1, len)],
      props.data.points[rangMod(ndx + 1, len)],
    ]);
  }
  geos.forEach((geo) => {
    const snapInfos = generateSnapInfos(geo, true, true, true);
    snapInfos.forEach((item) => {
      infos.add(item);
      addedInfos.push(item);
    });
  });
};

const endHandler = () => {
  clearInfos();
  emit("update");
};
</script>
