<template>
  <v-group v-if="shapeConfig">
    <v-line v-for="line in shapeConfig.lines" :config="line" />
    <v-text v-for="texConfig in shapeConfig.texts" :config="{ ...texConfig }" />
    <v-line
      :config="{
        points: [0, 0, size?.width, 0],
        strokeWidth: 30,
        stroke: '#fff',
        opacity: 0,
        ...invConfig,
      }"
      ref="line"
    />
    <slot />
  </v-group>
</template>

<script setup lang="ts">
import { computed, ref } from "vue";
import {
  useClickHandler,
  useGlobalResize,
  useGlobalVar,
  useHoverPointer,
  useStage,
  useViewerInvertTransform,
  useViewerInvertTransformConfig,
  useViewerTransform,
} from "../drawing/hook";
import { formatDate } from "@/utils";
import { TextConfig } from "konva/lib/shapes/Text";
import { Transform } from "konva/lib/Util";
import { Line, LineConfig } from "konva/lib/shapes/Line";
import { DC } from "../drawing/dec";

const { misPixel } = useGlobalVar();
const emit = defineEmits<{ (e: "updateCurrentTime", num: number): void }>();

const getText = (mis: number) => {
  const date = new Date(0);
  date.setHours(0);
  date.setSeconds(mis);
  const h = date.getHours();
  return h ? formatDate(date, "hh:mm:ss") : formatDate(date, "mm:ss");
};

const viewMat = useViewerTransform();
const invMat = useViewerInvertTransform();
const invConfig = useViewerInvertTransformConfig();
const { size } = useGlobalResize();

const timeRange = computed(() => {
  if (!size.value) return;
  const start = viewMat.value.point({ x: 0, y: 0 }).x;
  const lt = { x: start > 0 ? start : 0, y: 0 };
  const rt = { x: size.value!.width, y: 0 };
  const startPixel = invMat.value.point(lt).x;
  const endPixel = invMat.value.point(rt).x;
  const startTime = Math.floor(startPixel / misPixel);
  const endTime = Math.ceil(endPixel / misPixel);

  return { startTime, endTime };
});

const strokeWidth = 1;
const color = "#999";

const shapeConfig = computed(() => {
  if (!timeRange.value) return;

  const texts: TextConfig[] = [];
  const lines: LineConfig[] = [];

  for (let i = timeRange.value.startTime; i < timeRange.value.endTime; i++) {
    const x = i * misPixel;
    const line: LineConfig = {
      ...new Transform()
        .translate(x, 0)
        .scale(invConfig.value.scaleX, 1)
        .translate(-x, 0)
        .decompose(),
      stroke: color,
      hitStrokeWidth: 5,
      strokeWidth,
    };

    if (i % 10) {
      line.points = [x, 0, x, 4];
    } else {
      line.points = [x, 0, x, 12];
      texts.push({
        ...new Transform()
          .translate(x + 5 * invConfig.value.scaleX, 5)
          .scale(invConfig.value.scaleX, 1)
          .decompose(),
        text: getText(i),
        fontSize: strokeWidth * 12,
        fill: color,
        align: "left",
        verticalAlign: "top",
      });
    }
    lines.push(line);
  }

  return { texts, lines };
});

const line = ref<DC<Line>>();
useHoverPointer(line);

const stage = useStage();
const clickHandler = () => {
  const pos = stage.value!.getNode().pointerPos!;
  const x = invMat.value.point(pos).x;
  emit("updateCurrentTime", x / misPixel);
};
useClickHandler(line, clickHandler);
</script>
