<template>
  <div class="right-layout" @click="board.polygon.status.lightPointId = null">
    <div class="right-content">
      <el-form :inline="false" v-if="!queryMode">
        <el-form-item>
          <el-button type="primary" :icon="Plus" style="width: 100%" @click="addHandler">
            添加场景
          </el-button>
        </el-form-item>
      </el-form>
      <div class="tree-layout">
        <p class="sub-title">全部数据</p>
        <el-tree
          style="max-width: 600px"
          :data="treeNode"
          node-key="id"
          ref="treeRef"
          :show-checkbox="!queryMode"
          default-expand-all
          :expand-on-click-node="false"
        >
          <template #default="{ node, data }">
            <div
              class="tree-item"
              :class="{
                active: board.polygon.status.lightPointId === data.raw.id.toString(),
              }"
              @click.stop="
                !data.disable &&
                  (data.type === 'scene' ? flyScene(data) : flyPos(data.raw))
              "
            >
              <el-tooltip
                v-if="data.type === 'scene'"
                class="box-item"
                effect="dark"
                :content="data.raw.sceneName + ' ' + node.label"
                placement="top"
              >
                <span :class="{ disable: data.disable }" class="title">
                  <el-icon>
                    <Grid />
                  </el-icon>
                  <span>
                    <p>{{ data.raw.sceneName }}</p>
                  </span>
                  <span class="tree-scene-name">
                    <p>{{ node.label }}</p>
                  </span>
                </span>
              </el-tooltip>
              <el-tooltip
                v-else
                class="box-item"
                effect="dark"
                :content="data.raw.name || node.label.toString()"
                placement="top"
              >
                <div class="title-box">
                  <span :class="{ disable: data.disable }" class="title">
                    <el-icon>
                      <StateGpsIcon v-if="!data.disable" />
                      <StateGpsDIcon v-else />
                    </el-icon>
                    {{ node.label }}
                  </span>
                  <span :class="{ disable: data.disable }" class="name">
                    <span
                      class="color"
                      :style="{
                        backgroundColor:
                          pointColorMap[data.raw.type || PointTypeEnum.other],
                      }"
                    ></span>
                    {{ data.raw.name }} &nbsp;
                  </span>
                </div>
              </el-tooltip>
              <span class="oper" @click.stop>
                <template v-if="!queryMode">
                  <template v-if="data.type === 'scene'">
                    <el-icon color="#409efc" v-if="data.raw.creationMethod !== 2">
                      <Delete @click.stop="delSceneHandler([data.raw])" />
                    </el-icon>
                  </template>
                  <el-icon v-else color="#409efc">
                    <Edit @click.stop="inputPoint = data.raw" />
                  </el-icon>
                </template>
                <el-icon color="#409efc" style="margin-left: 8px">
                  <!-- root -->
                  <template v-if="data.raw.scenePos">
                    <FrameIcon
                      v-if="!data.run"
                      @click.stop="
                        data.type === 'scene'
                          ? gotoScene(data.raw, false)
                          : gotoPointPage(data.raw)
                      "
                    />
                  </template>
                  <template v-else>
                    <PanoramaIcon
                      v-if="!data.run"
                      @click.stop="
                        data.type === 'scene'
                          ? gotoScene(data.raw)
                          : gotoPointPage(data.raw)
                      "
                    />
                  </template>
                </el-icon>
              </span>
            </div>
          </template>
        </el-tree>
      </div>
    </div>

    <template v-if="!queryMode && treeNode.length">
      <el-button
        type="primary"
        :icon="Download"
        style="width: 100%"
        @click="exportFile(getSelectPoints(), 2, relics?.name, 'V2')"
      >
        导出本体边界坐标（V1.4模板）
      </el-button>
      <el-button
        type="primary"
        :icon="Download"
        style="width: 100%; margin-top: 20px; margin-left: 0"
        @click="exportFile(getSelectPoints(), 2, relics?.name, 'V1')"
      >
        导出本体边界坐标（V1.2模板）
      </el-button>

      <el-button
        type="primary"
        :icon="Download"
        style="width: 100%; margin-top: 20px; margin-left: 0"
        @click="exportImage(getSelectPoints(), relics?.name)"
      >
        下载全景图
      </el-button>
    </template>
  </div>

  <SingleInput
    v-if="inputPoint"
    :visible="!!inputPoint"
    @update:visible="inputPoint = null"
    :value="inputPoint"
    :update-value="updatePointName"
  />
</template>

<script setup lang="ts">
import { boardDataChange, noValidPoint, queryMode, validScene } from "./install";
import {
  Plus,
  Delete,
  Grid,
  Download,
  // DeleteLocation,
  Edit,
} from "@element-plus/icons-vue";
import { computed, onBeforeUnmount, ref, watchEffect } from "vue";
import {
  Scene,
  scenes,
  ScenePoint,
  updateScenePointName,
  gotoScene,
  relicsId,
  refreshScenes,
  boardData,
  scenePoints,
} from "@/store/scene";
import { relics } from "@/store/relics";
import SingleInput from "@/components/point-input.vue";
import { selectScenes } from "../quisk";
import { addRelicsScenesFetch, delRelicsScenesFetch } from "@/request";
import { exportFile, exportImage } from "./pc4Helper";
import { SceneStatus } from "@/store/scene";
import StateGpsIcon from "@/assets/state_gps.svg";
import StateGpsDIcon from "@/assets/state_gps_d.svg";
import PanoramaIcon from "@/assets/panorama.svg";
import FrameIcon from "@/assets/frame.svg";
import { alert, confirm } from "@/helper/message";
import {
  PolygonsPointAttrib,
  getWholeLineLinesByPointId,
  getWholeLinePoint,
  pointColorMap,
  PointTypeEnum,
} from "drawing-board";
import { flyScene, gotoPointPage, mapManage } from "./install";
import { board } from "./install";
// import { attachImageCoord, readExif } from "@/util/image-exif";
// import { saveAs } from "@/util/file-serve";

// const changfile = async (ev) => {
//   readExif(ev.target.files[0]);
//   const blob = await attachImageCoord(ev.target.files[0], [
//     127.101412416667,
//     37.338276944444,
//     5,
//   ]);
//   saveAs(blob);
// };

const inputPoint = ref<ScenePoint | null>(null);
const updatePointName = async (scenePoint: ScenePoint) => {
  const point = getWholeLinePoint(
    boardData.value,
    inputPoint.value.id.toString()
  ) as PolygonsPointAttrib;

  await Promise.all([
    boardDataChange(() => {
      if (point) {
        point.title = scenePoint.index
          ? scenePoint.index + "-" + scenePoint.name
          : scenePoint.name;
        point.type = scenePoint.type;
      }
    }),
    updateScenePointName(scenePoint),
  ]);
};

const flyPos = (point: ScenePoint) => {
  mapManage.map.getView().setCenter(point.pos);
  board.polygon.status.lightPointId = point.id.toString();
};

const relicsName = ref("");
watchEffect(() => (relicsName.value = relics.value?.name || ""));

const treeRef = ref<any>();
const treeNode = computed(() =>
  scenes.value.map((scene) => ({
    label: scene.sceneCode,
    id: scene.id,
    type: "scene",
    run: scene.calcStatus !== SceneStatus.SUCCESS,
    disable: !validScene(scene),
    raw: scene,
    children: scene.scenePos.map((pos) => ({
      label: pos.index || pos.uuid,
      run: scene.calcStatus !== SceneStatus.SUCCESS,
      disable: noValidPoint(pos),
      id: pos.id,
      type: "point",
      raw: { ...pos, name: pos.name, cameraType: scene.cameraType },
    })),
  }))
);

const getSelectPoints = () =>
  treeRef
    .value!.getCheckedNodes(false, false)
    .filter((option: any) => option.type === "point")
    .map((option: any) => option.raw) as ScenePoint[];

watchEffect(() => {
  if (treeRef.value) {
    board.polygon.status.selectPoiIds = getSelectPoints().map((point) =>
      point.id.toString()
    );
  }
});

const delScenesBeforeCheck = async (scenes: Scene[]) => {
  if (scenes.length === 0 || !(await confirm("确定要删除场景吗？"))) return true;
  for (const scene of scenes) {
    const que = scene.scenePos.some((pos) => {
      const id = pos.id.toString();
      return getWholeLineLinesByPointId(boardData.value, id).length !== 0;
    });
    if (que) {
      await alert("已存在矢量图数据，不可删除。");
      return false;
    }
    return true;
  }
};

const addHandler = async () => {
  const sceneCodes = scenes.value.map((scene) => scene.sceneCode);
  await selectScenes({
    scenes: scenes.value,
    selfScenes: scenes.value.filter((scene) => scene.creationMethod === 2),
    submit: async (nScene) => {
      const requests: Promise<any>[] = [];
      const delScenes = sceneCodes
        .filter((sceneCode) => !nScene.some((scene) => scene.sceneCode === sceneCode))
        .map((sceneCode) => scenes.value.find((scene) => scene.sceneCode === sceneCode)!);

      if (!(await delScenesBeforeCheck(delScenes))) {
        throw "不可删除";
      }

      delScenes.length &&
        requests.push(
          delRelicsScenesFetch(
            relicsId.value,
            delScenes.map((item) => ({ sceneCode: item.sceneCode, id: item.sceneId }))
          )
        );
      const addScenes = nScene.filter(({ sceneCode }) => !sceneCodes.includes(sceneCode));
      addScenes.length &&
        requests.push(
          addRelicsScenesFetch(
            relicsId.value!,
            addScenes.map((item) => ({ sceneCode: item.sceneCode, id: item.sceneId }))
          )
        );

      await Promise.all(requests);
      requests.length && (await refreshScenes());
    },
  });
};

const delSceneHandler = async (scenes: Scene[]) => {
  if (!(await delScenesBeforeCheck(scenes))) {
    return;
  }
  await delRelicsScenesFetch(
    relicsId.value,
    scenes.map((item) => ({ sceneCode: item.sceneCode, id: item.sceneId }))
  );
  await refreshScenes();
};

const pointClickHandler = ({ id }: { id: any }) => {
  const point = scenePoints.value.find((point) => point.id.toString() === id);
  point && gotoPointPage(point);
};

board.polygon.container.stage.on("click.checkPointSelect", (ev) => {
  if (ev.target === board.polygon.container.stage) {
    board.polygon.status.lightPointId = null;
  }
});
board.polygon.bus.on("clickPoint", pointClickHandler);
onBeforeUnmount(() => {
  board.polygon.bus.off("clickPoint", pointClickHandler);
  board.polygon.container.stage.off("click.checkPointSelect");
  board.polygon.status.lightPointId = null;

  // treeRef.value.setCheckedNodes([]);
  board.polygon.status.selectPoiIds = [];
});
</script>

<style lang="scss" scoped>
:deep(.el-tree-node__content) {
  --el-tree-node-content-height: 26px;
  line-height: 26px;
  user-select: none;
  margin-bottom: 8px;
}

:deep(.el-tree-node__children .el-tree-node__content) {
  --el-tree-node-content-height: 52px;

  & > label.el-checkbox {
    padding-top: 6px;
    align-items: flex-start;
  }
}

.tree-item {
  display: flex;
  width: calc(100% - 50px);
  align-items: flex-start;
  justify-content: space-between;
  font-size: var(--font14);

  &.active {
    color: rgba(64, 158, 255, 1);
  }

  .title {
    flex: 1;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    line-height: 26px;
    margin-right: 10px;

    p {
      margin: 0;
    }
  }

  .title-box {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 90%;
    overflow: hidden;
    flex-wrap: nowrap;

    .name {
      padding-left: 15px;
      color: #999;
      display: block;
      text-overflow: ellipsis; //文本溢出显示省略号
      overflow: hidden;
      white-space: nowrap; //文本不会换行

      .color {
        display: inline-block;
        width: 8px;
        height: 8px;
        margin-right: 8px;
        border-radius: 4px;
      }
    }
  }

  .oper {
    flex: none;
    line-height: 26px;
    vertical-align: middle;
  }
}

.disable {
  pointer-events: all;
}

.tree-layout {
  p {
    color: #303133;
  }

  .sub-title {
    font-size: 14px;
    font-weight: bolder;
  }
}

.right-layout {
  display: flex;
  height: 100%;
  flex-direction: column;

  .right-content {
    flex: 1;
    overflow-y: auto;
  }
}

.tree-layout .tree-scene-name {
  font-size: 10px;
  margin: 0;
  color: #999;
  p {
    margin: 0;
    max-width: 90%;
    text-overflow: ellipsis; //文本溢出显示省略号
    overflow: hidden;
    white-space: nowrap; //文本不会换行
  }
}
</style>
