<template>
  <Container
    :upload-resourse="uploadResourse"
    v-model:full="full"
    :ref="(d: any) => (draw = d?.draw)"
  >
    <template #header>
      <Header v-if="inited" :title="title" />
    </template>
    <template #slide>
      <Slide v-if="inited" />
    </template>
  </Container>

  <Dialog />
</template>

<script lang="ts" setup>
import Header from "./header.vue";
import Slide from "./slide.vue";
import Container from "../../../components/container/container.vue";
import { computed, nextTick, ref, watch, watchEffect } from "vue";
import { Draw } from "../../../components/container/use-draw";
import Dialog from "../../../dialog/dialog.vue";
import {
  tabulationData,
  refreshTabulationData,
  tableCoverKey,
  tableCoverScaleKey,
  tableCompassKey,
} from "../../store";
import { ImageData } from "@/core/components/image";
import { TextData } from "@/core/components/text";
import {
  genTabulationData,
  getCoverPaperScale,
  getRealPixel,
  repTabulationStore,
  setCoverPaperScale,
} from "./gen-tab";
import { IconData } from "@/core/components/icon";
import { Transform } from "konva/lib/Util";
import { MathUtils } from "three";
import { components } from "@/core/components";
import { ShapeType } from "@/index";
import { round } from "@/utils/shared";
import { PaperKey } from "@/example/components/slide/actions";
import { StoreData } from "@/core/store/store";
import { getImageSize } from "@/utils/shape";
import { tabCustomStyle } from "./defStyle";
import { defaultLayer } from "@/constant";

const uploadResourse = window.platform.uploadResourse;
const full = ref(false);
const draw = ref<Draw>();

const setMap = async (paperKey: PaperKey, compass: number, store: StoreData) => {
  const data = tabulationData.value;

  if (data.mapUrl && data.high && data.width) {
    const size = await getImageSize(data.mapUrl);
    const cover = {
      url: data.mapUrl,
      ...size,
      proportion: {
        scale: (data.width / size.width) * 1000,
        unit: "mm",
      },
    };
    if (!data.store.config) {
      const layer = await genTabulationData(paperKey, compass, cover);
      data.store.layers[defaultLayer] = layer;
    } else {
      await repTabulationStore(paperKey, compass, cover, store);
    }
  }
};

const inited = ref(false);
const init = async (draw: Draw) => {
  await refreshTabulationData();
  draw.config.showCompass = false;
  draw.config.showGrid = false;
  draw.config.showLabelLine = false;
  draw.config.showComponentSize = false;

  const config: any = tabulationData.value.store.config || {};
  const p = tabulationData.value.paperKey;
  await setMap(p, 0, tabulationData.value.store);
  draw.store.setStore({
    ...tabulationData.value.store,
    config: {
      ...config,
      compass: {
        rotation: 0,
        ...(config.compass || {}),
        url: "./icons/compass.svg",
      },
      proportion: {
        scale: 1 / getRealPixel(1, p),
        unit: "mm",
      },
    },
  });
  inited.value = true;
  return tabCustomStyle(p);
};
watch(draw, (draw, _, onCleanup) => {
  if (draw) {
    for (const type in components) {
      draw.menusFilter.setMenusFilter(type as ShapeType, (items) => {
        return items.filter((item) => item.label !== "隐藏");
      });
    }
    let des = false;
    let unInit: () => void;
    init(draw).then((_unInit) => {
      if (!des) {
        unInit = _unInit;
      } else {
        _unInit();
      }
    });
    onCleanup(() => {
      unInit && unInit();
      des = true;
    });
  }
});

const cover = computed(
  () => draw.value?.store.items.find((item) => item.key === tableCoverKey) as ImageData
);
const coverScale = computed({
  get: () =>
    cover.value &&
    Math.round(getCoverPaperScale(cover.value, tabulationData.value.paperKey)),
  set: (val) => {
    setCoverPaperScale(cover.value, tabulationData.value.paperKey, val);
  },
});
watch(cover, (cover, _, onCleanup) => {
  if (!cover || !draw.value || !cover.widthRaw || !cover.heightRaw || !cover.proportion)
    return;
  const mountMenus = draw.value.mountFilter;
  const menusFilter = draw.value.menusFilter;

  menusFilter.setShapeMenusFilter(cover.id, () => []);
  mountMenus.setShapeMenusFilter(cover.id, (des) => ({
    ...des,
    scale: {
      type: "fixProportion",
      label: "缩放比例",
      "layout-type": "row",
      get value() {
        return coverScale.value;
      },
      set value(val) {
        coverScale.value = val;
      },
      props: { min: 1 },
    },
    showScale: {
      type: "check",
      label: "显示比例",
      "layout-type": "row",
      get value() {
        return (cover as any).showScale || false;
      },
      set value(val) {
        (cover as any).showScale = val;
      },
      props: {},
    },
  }));
  onCleanup(() => {
    mountMenus.setShapeMenusFilter(cover.id);
    menusFilter.setShapeMenusFilter(cover.id);
  });
});

const coverScaleText = computed(() => {
  return draw.value?.store.items.find(
    (item) => item.key === tableCoverScaleKey
  ) as TextData;
});
watch(
  () => {
    return {
      text: coverScaleText.value,
      exists: cover.value,
      show: (cover.value as any)?.showScale,
      content: coverScale.value ? `1:${coverScale.value}` : "",
    };
  },
  ({ text, show, exists, content }) => {
    if (!text) return;
    draw.value!.history.preventTrack(() => {
      if (!exists) {
        draw.value!.store.delItem("text", text.id);
      } else {
        draw.value!.store.setItem("text", {
          value: { hide: !show, content },
          id: text.id,
        });
      }
    });
  },
  { flush: "post" }
);

const compass = computed(
  () => draw.value?.store.items.find((item) => item.key === tableCompassKey) as IconData
);
watch(compass, (compass, _, onCleanup) => {
  if (!compass || !draw.value) return;
  const mountMenus = draw.value.mountFilter;
  const menusFilter = draw.value.menusFilter;
  menusFilter.setShapeMenusFilter(compass.id, () => []);
  mountMenus.setShapeMenusFilter(compass.id, (des) => ({
    // ...des,
    rotate: {
      type: "num",
      label: "旋转角度",
      default: 0,
      props: {
        min: 0,
        max: 360,
      },
      "layout-type": "column",
      sort: 3,
      get value() {
        return round((new Transform(compass.mat).decompose().rotation + 360) % 360, 1);
      },
      set value(val) {
        const config = new Transform(compass.mat).decompose();
        compass.mat = new Transform()
          .translate(config.x, config.y)
          .scale(config.scaleX, config.scaleY)
          .rotate(MathUtils.degToRad(val)).m;
        nextTick(() => {
          draw.value?.stage!.findOne(`#${compass.id}`)?.fire("bound-change");
        });
      },
    },
  }));
  onCleanup(() => {
    mountMenus.setShapeMenusFilter(compass.id);
    menusFilter.setShapeMenusFilter(compass.id);
  });
});

const title = computed(() => tabulationData.value?.title || "图纸");
watchEffect(() => {
  document.title = title.value;
});
</script>
