<template>
  <v-group :config="{ listening: false }">
    <template v-for="line in lines">
      <v-line
        v-for="p in line.points"
        :config="{
          stroke: stroke,
          strokeWidth: strokeWidth,
          points: flatPositions(p),
        }"
      />
      <v-textPath
        :config="{
          fill: stroke,
          align: 'center',
          fontSize,
          textBaseline: 'middle',
          ...line.textConfig,
        }"
      />
    </template>
  </v-group>
</template>

<script lang="ts" setup>
import { computed } from "vue";
import { LineData } from "../line";
import {
  getPolygonDirection,
  getVectorLine,
  lineLen,
  lineVector,
  lineVerticalVector,
  Pos,
  vector,
} from "@/utils/math";
import { flatPositions } from "@/utils/shared";
import { useProportion } from "@/core/hook/use-proportion";
import { TextPathConfig } from "konva/lib/shapes/TextPath";

const props = withDefaults(
  defineProps<{
    data: Required<Pick<LineData, "points" | "strokeWidth">>;
    stroke?: string;
    strokeWidth?: number;
    closed?: boolean;
  }>(),
  { stroke: "#999", strokeWidth: 1 }
);

const fontSize = computed(() => 10 + props.strokeWidth * 2);
const len = computed(() =>
  props.closed ? props.data.points.length : props.data.points.length - 1
);
const getLine = (ndx: number) =>
  [
    props.data.points[ndx % props.data.points.length],
    props.data.points[(ndx + 1) % props.data.points.length],
  ] as [Pos, Pos];
const isClockwise = computed(() => getPolygonDirection(props.data.points) <= 0);

const proportion = useProportion();
const margin = computed(() => -(props.data.strokeWidth + 10));
const lines = computed(() => {
  const lines: { points: Pos[][]; textConfig: TextPathConfig }[] = [];
  for (let i = 0; i < len.value; i++) {
    const line = getLine(i);
    const lineOffset = isClockwise.value ? margin.value : -margin.value;
    const vv = lineVerticalVector(line);
    const offset = vv.multiplyScalar(lineOffset);
    const p = [vector(line[0]).add(offset), vector(line[1]).add(offset)];
    const text = proportion.transform(lineLen(...line));
    const w = fontSize.value * text.length;
    const lw = lineLen(p[0], p[1]);
    if (w > lw) {
      continue;
    }
    const lv = lineVector(p);
    const line1 = getVectorLine(lv, p[0], (lw - w) / 2);
    const [_, start2] = getVectorLine(lv, line1[1], w);
    const line2 = getVectorLine(lv, start2, (lw - w) / 2);

    lines.push({
      points: [line1, line2],
      textConfig: {
        text: proportion.transform(lineLen(...line)),
        x: 0,
        y: 0,
        data: `M${p[0].x},${p[0].y} L${p[1].x},${p[1].y}`,
      },
    });
  }
  return lines;
});
</script>
