<template>
  <div class="pano-layout" v-loading="loading">
    <canvas ref="panoDomRef"></canvas>
    <div class="btns">
      <el-button
        size="large"
        type="primary"
        style="margin-right: 20px; width: 100px"
        @click="photo"
      >
        屏幕拍照
      </el-button>
      <el-button
        size="large"
        style="margin-right: 20px; width: 100px"
        @click="copyGis"
        v-if="point?.pos && point.pos.length"
      >
        复制经纬度
      </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.name || ''"
    :update-value="tex => updateScenePointName(point!, tex)"
    title="修改点位名称"
  />
</template>

<script setup lang="ts">
import SingleInput from "@/components/single-input.vue";
import { router, setDocTitle } from "@/router";
import { mergeFuns } from "@/util";
import { computed, onMounted, onUnmounted, ref, watchEffect } from "vue";
import { init } from "./env";
import {
  updateScenePointName,
  getPointPano,
  ScenePoint,
  scenePoints,
} from "@/store/scene";
import { copyText, toDegrees } from "@/util";
import { ElMessage } from "element-plus";
import saveAs from "@/util/file-serve";
import { DeviceType } from "@/store/device";
import { initRelics, relics } from "@/store/relics";

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>();
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 copyGis = async () => {
  const pos = point.value!.pos as number[];
  await copyText(
    `经度:${toDegrees(pos[0])}, 纬度: ${toDegrees(pos[1])}, 高程: ${pos[2]}`
  );
  ElMessage.success("经纬度高程复制成功");
};

const photo = () => {
  loading.value = true;
  setSize(3, 1920, 1080);
  panoDomRef.value!.toBlob(async (blob) => {
    if (blob) {
      await saveAs(blob, `${relics.value?.name}.jpg`);
      ElMessage.success("图片导出成功");
    }

    setSize(devicePixelRatio);
    loading.value = false;
  }, "image/jpg");
};

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);
  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.destory,
    () => {
      window.removeEventListener("resize", resizeHandler);
    }
  );
});

onUnmounted(() => mergeFuns(...destroyFns)());
watchEffect(() => {
  if (router.currentRoute.value.name === "pano" && point.value) {
    setDocTitle(point.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>
