<template>
  <v-group :config="groupConfig" v-if="groupConfig && svg" ref="shape">
    <v-group :config="initDecMat" name="rep-position">
      <v-rect :config="rectConfig" name="repShape" />
      <v-path v-for="config in pathConfigs" :config="config" name="icon-path" />
    </v-group>
  </v-group>
</template>

<script lang="ts" setup>
import { defaultStyle, IconData } from "./icon.ts";
import { computed, ref, watch } from "vue";
import { getSvgContent, parseSvgContent, SVGParseResult } from "@/utils/resource.ts";
import { Group } from "konva/lib/Group";
import { DC } from "@/deconstruction.js";
import { Transform } from "konva/lib/Util";
import { useViewerInvertTransform, useViewSize } from "@/core/hook/use-viewer.ts";
import { getFixPosition } from "@/utils/bound.ts";

const props = defineProps<{ data: IconData; addMode?: boolean }>();
const svg = ref<SVGParseResult | null>(null);
const shape = ref<DC<Group>>();
const data = computed(() => ({ ...defaultStyle, ...props.data }));

defineExpose({
  get shape() {
    return shape.value;
  },
});

watch(
  () => data.value.url,
  async (url) => {
    svg.value = null;
    const svgContent = await getSvgContent(url);

    const content = parseSvgContent(svgContent);
    if (content.paths.length === 0) {
      svg.value = null;
      console.error(props.data.url, content, "路径数据不正确不是svg");
    } else {
      svg.value = content;
    }
  },
  { immediate: true }
);

const scale = computed(() => {
  if (!svg.value) return null;

  let w = data.value.width;
  let h = data.value.height;
  w = w || svg.value.width || 0;
  h = h || svg.value.height || 0;

  const scale = {
    x: w / svg.value.width,
    y: h / svg.value.height,
  };
  return scale;
});

const pathConfigs = computed(() => {
  if (!svg.value) return [];
  return svg.value.paths.map((path) => ({
    ...path,
    ...data.value,
    id: undefined,
    lineWidth: 1000,
    zIndex: undefined,
    offset: { x: svg.value!.x, y: svg.value!.y },
  }));
});
const initDecMat = computed(() => {
  if (!svg.value || !scale.value) return;
  return new Transform()
    .scale(scale.value.x, scale.value.y)
    .multiply(new Transform().translate(-svg.value.width / 2, -svg.value.height / 2))
    .decompose();
});

const viewInvTransform = useViewerInvertTransform();
const size = useViewSize();
const groupConfig = computed(() => {
  let mat = new Transform(data.value.mat);

  if (data.value.fixScreen) {
    if (!size.value) return {};
    const pos = getFixPosition(data.value.fixScreen, data.value, size.value);
    pos.x += data.value.width / 2;
    pos.y += data.value.height / 2;
    mat = viewInvTransform.value.copy().translate(pos.x, pos.y).multiply(mat);
  }

  return {
    ...mat.decompose(),
    zIndex: undefined,
    listening: data.value.listening,
    id: data.value.id,
    opacity: props.addMode ? 0.3 : 1,
  };
});

const rectConfig = computed(() => {
  if (!svg.value) return null;
  return {
    fill: data.value.coverFill,
    id: "rep",
    stroke: data.value.coverStroke,
    opacity: data.value.coverOpcatiy,
    strokeWidth: data.value.coverStrokeWidth,
    width: svg.value.width,
    height: svg.value.height,
  };
});
</script>
