<template>
  <div class="pano-layout" v-loading="loading" :element-loading-text="loadingStr">
    <canvas ref="panoDomRef"></canvas>
    <div class="btns">
      <el-button
        size="large"
        type="primary"
        style="margin-right: 20px; width: 100px"
        @click="photo"
      >
        屏幕拍照
      </el-button>
      <!-- <el-input-number
        style="margin-right: 20px"
        v-model="tempRadion"
        :precision="2"
        :step="0.01"
        :min="1"
        :max="3"
      /> -->
      <el-button
        size="large"
        style="margin-right: 20px; width: 100px"
        @click="copyGis"
        v-if="point && !noValidPoint(point)"
      >
        复制经纬度
      </el-button>
      <el-button
        size="large"
        type="primary"
        style="width: 100px"
        @click="update = true"
        v-if="router.currentRoute.value.name === 'pano'"
      >
        测点说明
      </el-button>
    </div>
  </div>
  <SingleInput
    v-if="point"
    :visible="update"
    @update:visible="update = false"
    :value="point"
    :update-value="(npoint) => updateScenePointName(npoint)"
  />
</template>

<script setup lang="ts">
import SingleInput from "@/components/point-input.vue";
import { router, setDocTitle } from "@/router";
import { mergeFuns, round } from "@/util";
import { glMatrix } from "gl-matrix";
import { computed, nextTick, onMounted, onUnmounted, ref, watchEffect } from "vue";
import { init } from "./env";
import {
  updateScenePointName,
  getPointPano,
  ScenePoint,
  scenePoints,
} from "@/store/scene";
import { copyText, toDegrees, getTextBound } from "@/util";
import { ElMessage } from "element-plus";
import saveAs from "@/util/file-serve";
import { DeviceType } from "@/store/device";
import { initRelics, relics } from "@/store/relics";
import { noValidPoint } from "../map/install";
import { addWatermark } from "@/util/image";

type Params = { pid?: string; relicsId?: string } | null;
const params = computed(() => router.currentRoute.value.params as Params);
const panoDomRef = ref<HTMLCanvasElement>();
const destroyFns: (() => void)[] = [];
const point = ref<ScenePoint>();
const tempRadion = ref(3.0);

watchEffect(() => {
  if (params.value?.pid) {
    const pid = Number(params.value!.pid);
    point.value = scenePoints.value.find((scene) => scene.id === pid);

    if (!point.value) {
      initRelics(Number(params.value.relicsId)).then(() => {
        point.value = scenePoints.value.find((scene) => scene.id === pid);
        if (!point.value) {
          router.replace({ name: "relics" });
        }
      });
    }
  }
});

const panoUrls = computed(() => {
  return (
    point.value && getPointPano(point.value, point.value.cameraType === DeviceType.CLUNT)
  );
});
const update = ref(false);
const loading = ref(false);
const loadingStr = ref("");

const getGis = () => {
  const pos = point.value!.pos as number[];
  return `经度: ${toDegrees(pos[0])}\n纬度: ${toDegrees(pos[1])}\n高程: ${round(
    pos[2],
    4
  )}`;
};

const copyGis = async () => {
  await copyText(getGis());
  ElMessage.success("经纬度高程复制成功");
};

const photo = async () => {
  loading.value = true;
  loadingStr.value = "原图提取中";
  await new Promise((resolve) => setTimeout(resolve, 300));
  const ration = tempRadion.value;
  console.log("ration", ration);
  setSize(ration, 1920, 1080);
  let dataURL: Blob | string = panoDomRef.value.toDataURL("image/jpeg", 1);
  if (!noValidPoint(point.value)) {
    dataURL = await addWatermark(dataURL, point.value!.pos, ration);
  }

  await saveAs(dataURL, `${relics.value?.name}.jpg`);
  ElMessage.success("图片导出成功");
  setSize(devicePixelRatio);
  loading.value = false;
};

let pano: ReturnType<typeof init>;
const setSize = (ration: number, w?: number, h?: number) => {
  const canvas = panoDomRef.value!;
  canvas.width = (w || canvas.offsetWidth) * ration;
  canvas.height = (h || canvas.offsetHeight) * ration;
  pano.setSize([canvas.width, canvas.height]);
};

onMounted(() => {
  if (!panoDomRef.value) throw "没有canvas DOM";
  pano = init(panoDomRef.value, 0);
  const resizeHandler = () => {
    setSize(devicePixelRatio);
  };
  resizeHandler();

  window.addEventListener("resize", resizeHandler);
  destroyFns.push(
    watchEffect(() => {
      if (panoUrls.value) {
        loading.value = true;
        pano.changeUrls(panoUrls.value).then(() => (loading.value = false));
        pano.setYaw(
          point.value.cameraType === DeviceType.CLUNT ? glMatrix.toRadian(180) : 0
        );
      }
    }),
    pano.destory,
    () => {
      window.removeEventListener("resize", resizeHandler);
    }
  );
});

onUnmounted(() => mergeFuns(...destroyFns)());
watchEffect(() => {
  if (router.currentRoute.value.name.toString().includes("pano") && point.value) {
    setDocTitle(point.value.index.toString() || relics.value.name);
  }
});
</script>

<style scoped lang="scss">
.pano-layout,
canvas {
  width: 100%;
  height: 100%;
}

.pano-layout {
  position: relative;
  .btns {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 40px;
    z-index: 1;
  }
}
</style>
