<template>
  <div
    class="draw-layout"
    @contextmenu.prevent
    :style="{ cursor: cursorStyle }"
    ref="layout"
  >
    <div class="mount-mask" :id="DomOutMountId" />
    <div
      class="draw-content"
      :style="fix && { width: size?.width + 'px', height: size?.height + 'px' }"
    >
      <div class="mount-mask" :id="DomMountId" />

      <v-stage ref="stage" :config="size" v-if="layout">
        <v-layer :config="viewerConfig" id="formal">
          <Back />
          <!--	不可去除，去除后移动端拖拽会有溢出	-->
          <BackGrid v-if="expose.config.showGrid" />
          <component
            :is="GroupComponentMap[type]"
            v-for="type in types"
            :type="type"
            :key="type"
          />
        </v-layer>
        <!--	临时组，提供临时绘画，以及高频率渲染	-->
        <v-layer :config="viewerConfig" id="temp">
          <template v-if="mode.include(Mode.draw)">
            <TempShapeGroup v-for="type in types" :type="type" :key="type" />
          </template>
        </v-layer>
        <v-layer id="helper">
          <Compass v-if="config.showCompass" />
          <ActiveBoxs />
          <SnapLines />
          <SplitLine v-if="expose.config.showLabelLine" />
          <Debugger v-if="isDev" />
          <Border />
        </v-layer>
      </v-stage>
    </div>
  </div>
</template>

<script lang="ts" setup>
import ShapeGroup from "./group.vue";
import Back from "../helper/back.vue";
import Border from "../helper/facade.vue";
import TempShapeGroup from "./draw-group.vue";
import ActiveBoxs from "../helper/active-boxs.vue";
import SnapLines from "../helper/snap-lines.vue";
import BackGrid from "../helper/back-grid.vue";
import SplitLine from "../helper/split-line.vue";
import Debugger from "../helper/debugger.vue";
import Compass from "../helper/compass.vue";
import { ShapeType, components } from "../components";
import {
  InstanceProps,
  useCursor,
  useInstanceProps,
  useMode,
  useStage,
} from "../hook/use-global-vars.ts";
import { useViewerTransformConfig } from "../hook/use-viewer.ts";
import { useGlobalResize } from "../hook/use-event.ts";
import { useAutoService, useExpose } from "../hook/use-expose.ts";
import { DomMountId, DomOutMountId } from "../../constant";
import { useStore } from "../store/index.ts";
import { Mode } from "@/constant/mode.ts";
import { computed, getCurrentInstance, ref, watch } from "vue";
import { install } from "../../install-lib.ts";
import { useConfig } from "../hook/use-config.ts";
import { getEmptyStoreData } from "../store/store.ts";

const instance = getCurrentInstance();
install(instance!.appContext.app);

const props = defineProps<InstanceProps>();
const store = useStore();
watch(
  () => props.data,
  (data) => store.setStore(data || getEmptyStoreData())
);

useInstanceProps().set(props);
useAutoService();

const isDev = import.meta.env.DEV;
const stage = useStage();
const { size, fix } = useGlobalResize();
const layout = ref();
const viewerConfig = useViewerTransformConfig();
const types = Object.keys(components) as ShapeType[];
const mode = useMode();
const config = useConfig();

const GroupComponentMap = types.reduce((map, type) => {
  map[type] = components[type].GroupComponent || ShapeGroup;
  return map;
}, {} as any);

const cursor = useCursor();
const cursorStyle = computed(() => {
  if (cursor.value.includes(".")) {
    return `url(${cursor.value}), auto`;
  } else {
    return cursor.value;
  }
});

const expose = useExpose();
defineExpose(expose);
</script>

<style scoped lang="scss">
.draw-layout {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;

  .draw-content {
    position: relative;
    width: 100%;
    height: 100%;
  }
}

.mount-mask {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 999;
}
</style>
