<template>
  <div class="map-layout">
    <Teleport to=".header" v-if="isMounted">
      <div class="custom_bar">
        <div class="back_container">
          <el-button :icon="Back" circle type="primary" @click="router.back()" />
        </div>
        <div class="nav_container">
          <div
            class="nav_item"
            :class="{ active: isCurrentTab(0) }"
            @click="handleTabs(0)"
          >
            <el-icon size="20">
              <locationIcon />
            </el-icon>
            <span>坐标</span>
          </div>
          <div
            class="nav_item"
            :class="{ active: isCurrentTab(1) }"
            @click="handleTabs(1)"
          >
            <el-icon size="20">
              <vectorIcon />
            </el-icon>
            <span>矢量图</span>
          </div>
        </div>
      </div>
    </Teleport>
    <div id="map" class="map-container" ref="mapContainer" @click.stop>
      <div class="map-component">
        <el-select
          v-model="tileType"
          placeholder="选择底图"
          style="width: 120px"
          class="tile-type-select"
        >
          <el-option
            v-for="item in tileOptions"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>
      </div>

      <div class="board" ref="boardContainer"></div>
    </div>
    <div class="right-control">
      <MapRight
        v-if="isCurrentTab(0)"
        @fly-point="flyScenePoint"
        @fly-scene="flyScene"
        @goto-point="gotoPointPage"
      />
      <MapRightPoly
        @del="handlePolysDel"
        @edit="handlePolysEdit"
        :data="boardData"
        v-if="boardData && isCurrentTab(1)"
      >
      </MapRightPoly>
    </div>

    <Teleport to="body" v-if="isMounted">
      <!-- <el-button class="temp_btn" @click="clearPolys">后端全清</el-button> -->
      <div
        class="draw-global-icon"
        v-if="isCurrentTab(1) && !isEditDrawingMode"
        @click="handleBoardDraw"
      >
        <el-icon size="36">
          <picpenIcon />
        </el-icon>
      </div>
    </Teleport>
  </div>
</template>

<script setup lang="ts">
import MapRight from "./map-right.vue";
import { router, setDocTitle } from "@/router";
import { Manage } from "./openlayer";
import { ScenePoint, Scene, scenePoints, scenes, SceneStatus } from "@/store/scene";
import { initRelics, initSelfRelics, relics } from "@/store/relics";
import { onMounted, ref, watchEffect, watch, onUnmounted, computed } from "vue";
import { createBoard, PolygonsPointAttrib } from "drawing-board";
import MapRightPoly from "./map-right-poly.vue";
import { Back } from "@element-plus/icons-vue";
import vectorIcon from "@/assets/vector.svg";
import picpenIcon from "@/assets/pic_pen.svg";
import locationIcon from "@/assets/location.svg";
import {
  addOrUpdateDrawingFetch,
  getDrawingDetailFetch,
  DrawingParamsType,
  DrawingDataType,
  PolyDataType,
} from "@/request/drawing.ts";
// import { relicsPolyginsFetch } from "@/request";
// import { Grid, LocationInformation } from "@element-plus/icons-vue";

import { mapManageInit, flyUserCenter, tileOptions, tileType } from "./map-flow";

const scenePosTransform = (scenes: Scene[]) => {
  const points: PolygonsPointAttrib[] = [];

  scenes.forEach((scene) => {
    if (scene.calcStatus !== SceneStatus.SUCCESS) {
      return;
    }
    scene.scenePos.forEach((pos) => {
      if (!pos.pos || pos.pos.length === 0) {
        return;
      }
      points.push({
        x: pos.pos[0],
        y: pos.pos[1],
        title: pos.name,
        id: pos.id.toString(),
        rtk: true,
      });
    });
  });
  return points;
};

const relicsId = computed(() => router.currentRoute.value.params.relicsId || "");

const gotoPointPage = (point: ScenePoint) => {
  router.push({
    name: router.currentRoute.value.name === "map" ? "pano" : "query-pano",
    params: { pid: point.id },
  });
};

const isMounted = ref(false);
const currentTab = ref(0);
const isCurrentTab = ref((index: number) => currentTab.value === index);
const isEditDrawingMode = ref(false);

const autoInitPos = () => {
  const scene = scenes.value.find(
    (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
  );
  if (scene) {
    flyScene(scene);
    return true;
  } else {
    return false;
  }
};
const flyPos = (pos: number[]) => mapManage.map.getView().setCenter(pos);

const flyScene = (scene: Scene) => {
  const totalPos = [0, 0];
  let numCalc = 0;
  for (let i = 0; i < scene.scenePos.length; i++) {
    const coord = scene.scenePos[i].pos as number[];
    if (coord && coord.length > 0) {
      totalPos[0] += coord[0];
      totalPos[1] += coord[1];
      numCalc++;
    }
  }

  totalPos[0] /= numCalc;
  totalPos[1] /= numCalc;
  flyPos(totalPos);
};

const flyScenePoint = (point: ScenePoint) => {
  flyPos(point.pos);
  board.polygon.status.activePointId = point.id.toString();
};

watch(
  () => [router.currentRoute.value.name, router.currentRoute.value.params?.relicsId],
  ([name, rid], old) => {
    if (["map", "query-map"].includes(name as string) && (!old || old[1] !== rid)) {
      relics.value = undefined;
      const fn = name === "map" ? initSelfRelics : initRelics;
      fn(Number(rid)).finally(() => {
        if (!relics.value) {
          return router.replace({ name: "relics" });
        }
        if (mapManage && !autoInitPos()) {
          flyUserCenter(mapManage);
        }
        // const points = scenePosTransform(scenes.value);
        // console.log("scenePosTransform", points, scenes.value);
        // board.setData(
        //   {
        //     points: points,
        //     lines: [],
        //     polygons: [],
        //   },
        //   router.currentRoute.value.params.relicsId as string
        // );
        initCroodTabdata();

        board.polygon.bus.on("clickPoint", (bpoint) => {
          const point =
            bpoint.id &&
            scenePoints.value.find((point) => point.id.toString() === bpoint.id);
          point && gotoPointPage(point);
        });

        // relicsPolyginsFetch().then((data) => {
        //   relics.value;
        //   board.setData(data, router.currentRoute.value.params.relicsId as string);
        //   board.polygon.bus.on("clickPoint", (bpoint) => {
        //     const point =
        //       bpoint.id &&
        //       scenePoints.value.find((point) => point.id.toString() === bpoint.id);
        //     point && gotoPointPage(point);
        //   });
        // });
      });
    }
  },
  { immediate: true }
);

watch(
  () => {
    const scene = scenes.value.find(
      (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
    );
    return scene?.sceneCode;
  },
  (firstCode) => {
    if (firstCode && mapManage) {
      autoInitPos();
    }
  }
);

watchEffect(() => {
  if (
    ["map", "query-map"].includes(router.currentRoute.value.name as string) &&
    relics.value
  ) {
    setDocTitle(relics.value.name);
  }
});

// ----------流程--------
const mapContainer = ref<HTMLDivElement>();
const boardContainer = ref<HTMLDivElement>();
let mapManage: Manage;

const board = createBoard();
const boardData = ref<DrawingDataType | null>(null);
let endEdithandler;

onMounted(async () => {
  mapManage = mapManageInit(mapContainer.value!);
  board.setProps({
    dom: boardContainer.value!,
    map: mapManage.map,
  });
  isMounted.value = true;
  const borardPolyData = computed(() => board.getData());
  watch(
    borardPolyData,
    (updater) => {
      if (updater) {
        boardData.value = (updater as any) as DrawingDataType;
      }
    },
    { immediate: true, deep: true }
  );
});

onUnmounted(() => {
  mapManage.map.dispose();
  board.destory();
});

const handleTabs = (index: number) => {
  currentTab.value = index;
};

const handleBoardDraw = () => {
  console.log("开始start draw", String(relicsId.value), board.polygon);
  try {
    endEdithandler = board.polygon.editPolygon();
    isEditDrawingMode.value = true;
    board.polygon.bus.on("penEndHandler", handleSyncDataToServer);
  } catch (error) {
    console.error("error", error);
  }
};
const handleSyncDataToServer = () => {
  setTimeout(async () => {
    console.log("handleSyncDataToServer");
    const data = (board.getData() as any) as DrawingDataType;
    console.log(data);
    boardData.value = data;
    const param: DrawingParamsType = {
      data: data,
      relicsId: String(relicsId.value),
    };
    patchPolyName(data);

    await addOrUpdateDrawingFetch(param);
    isEditDrawingMode.value = false;

    board.polygon.bus.off("penEndHandler");
    if (endEdithandler) {
      console.log("end edit");
    }
  }, 1000);
};

const patchPolyName = (data: DrawingDataType) => {
  const poly = data.polygons;
  poly?.forEach((item) => {
    if (!item.name) {
      item.name = "本体边界" + item.id;
    }
  });
};

watch(
  currentTab,
  (tab, oldTab) => {
    console.log("tab", tab);
    if (tab === 1) {
      initPolyTabData();
    }
    if (oldTab == 1 && tab === 0) {
      initCroodTabdata();
    }
  },
  { deep: true }
);
const initCroodTabdata = async () => {
  const points = scenePosTransform(scenes.value);
  console.log("initCroodTabdata", points, scenes.value);
  board.setData({
    id: String(relicsId.value),
    points: points,
    lines: [],
    polygons: [],
  });
};

const initPolyTabData = async () => {
  try {
    setTimeout(async () => {
      const res = await getDrawingDetailFetch(String(relicsId.value));
      const points = scenePosTransform(scenes.value);
      // console.log("res", points, res.data);
      if (res.data) {
        boardData.value = res.data;
        boardData.value.points = points.concat(res.data.points);
        console.log(boardData.value);
        board.setData({ ...boardData.value, id: String(relicsId.value) });
      }
    }, 500);
  } catch (error) {}
};

const handlePolysDel = (id: string) => {
  try {
    board.polygon.removePolygon(id);
    handleSyncDataToServer();
  } catch (error) {
    console.error("handlePolysDel", error);
  }
};

const handlePolysEdit = (item: PolyDataType) => {
  console.log("handlePolysEdit", item);
  const data = (board.getData() as any) as DrawingDataType;
  const index = data.polygons.findIndex((i) => item.id === i.id);
  data.polygons[index] = item;
  handleSyncDataToServer();
};

// const clearPolys = async () => {
//   await addOrUpdateDrawingFetch({
//     relicsId: String(relicsId.value),
//     data: {
//       points: [],
//       polygons: [],
//       lines: [],
//     },
//   });
// };
</script>

<style lang="scss">
.tooltip {
  pointer-events: none;
}

.map-layout {
  display: flex;
  flex-direction: row;
  height: 100%;
}

.map-container {
  flex: 1;
  position: relative;
}

.right-control {
  flex: none;
  width: 320px;
  padding: 15px;

  border-left: 1px solid var(--border-color);
}

.map-component {
  width: 100%;
  height: 100%;
  position: relative;
}

.active {
  cursor: pointer;
}

.active-point {
  position: absolute;
  pointer-events: none;
}

.map-component {
  pointer-events: none;
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  z-index: 9;
}

.env {
  width: 100%;
  height: 100%;
}

.tile-type-select {
  pointer-events: all;
  position: absolute;
  right: 10px;
  top: 10px;
}

.scale-view {
  --color: #fff;
  position: absolute;
  left: 20px;
  bottom: 20px;
  height: 8px;
  color: var(--color);
  text-align: center;
  border: 1px solid var(--color);
  border-top: none;
  z-index: 1;
  font-size: 14px;
  display: flex;
  align-items: end;

  &.light {
    --color: #fff;

    > div {
      text-shadow: 0 0 2px #000;
    }
  }

  &.dark {
    --color: #000;

    > div {
      text-shadow: 0 0 2px #fff;
    }
  }
}

.board {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  z-index: 1;
}

.custom_bar {
  width: 60px;
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  background-color: white;

  // padding-top: 76px;
  .back_container {
    display: flex;
    justify-content: center;
    align-items: center;
    color: #606266;
    height: 76px;
  }

  .nav_container {
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #606266;

    .nav_item {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding: 10px 0;
      cursor: pointer;
      user-select: none;
      width: 100%;
      span {
        line-height: 26px;
        font-size: var(--font14);
      }

      &.active {
        .icon {
          color: #409eff;
        }

        color: #409eff;
        background-color: #ecf5ff;
        position: relative;

        &::before {
          content: "";
          height: 100%;
          width: 4px;
          position: absolute;
          top: 0;
          left: 0;
          background-color: #409eff;
        }
      }
    }
  }
}

.draw-global-icon {
  width: 64px;
  height: 64px;
  background: #ffffff;
  border-radius: 50%;
  position: fixed;
  z-index: 1000;
  transform: translateX(calc(-1 * calc(50% - 300px)));
  left: calc(50% - 300px);
  top: 90%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #409eff;
}

.temp_btn {
  top: 40px;
  position: fixed;
  z-index: 1000;
  top: 10px;
  transform: translateX(calc(-1 * calc(50% - 300px)));
  left: calc(50% - 300px);
}
</style>
