<template>
  <div class="full-w-h">
    <wMap :mapId="'situation-map'" ref="wMap"/>
    <msgs :clickCrossData="clickCrossData" :isCrossDetail="isCrossDetail" v-if="!loading"
          @showCrossStatus="showCrossStatus" @openCrossIndexDetail="openCrossIndexDetail" @showPolygon="showPolygon"
          @openGreenWaveDialog="openGreenWaveDialog" :show="boxesShow"></msgs>
    <div :class="boxesShow ? '' : 'hideBackToMain'" @click="backToMain" v-if="isCrossDetail" class="backToMain"></div>
    <!--切换图层 收起放开侧边栏-->
    <layers-switch ref="switch" :show="boxesShow" @changeCheck="changeCheck" @visibleChange="visibleChange"
                   :class="boxesShow ? 'generalSwitch' : 'rightSwitch'"/>
    <!--路口指标详情弹窗-->
    <cross-detail :cross-detail-data="crossData" dialogId="crossDetailShow" v-if="dialogVisible.crossDetailShow"
                  @actionFinished="actionFinished"/>
    <!--路口绿波信息弹窗-->
    <green-wave :greenId="greenId" :waveTitle="waveTitle" dialogId="greenWaveShow" v-if="dialogVisible.greenWaveShow"
                @actionFinished="actionFinished"/>
    <!--设备图例控制-->
    <equipment-switch :boxesShow="boxesShow" @equipmentChange="equipmentChange" v-if="currentCheck === 'fourth'"/>
  </div>
</template>

<script>
import Vue from "vue";
import wMap from "../../components/Standard/mapMapbox.vue";
import msgs from "./msgs/index.vue";
import LayersSwitch from "./switchers/layersSwitch.vue";
import mapAssets from "@/config/holo/mapAssets";
import CrossDetail from "@/views/signal/dialogs/crossDetail.vue";
import GreenWave from "@/views/signal/dialogs/greenWave/index.vue";
import * as mapTool from "@/utils/mapboxTools";
import {initWs} from "@/config/holo/websocket";
import equipmentPopup from "./mapPopup/equipmentPopup.vue";
import dict from "../../config/holo/dictionary";
import vehicleDetail from "./mapPopup/vehicleDetail.vue";
import EquipmentSwitch from "./switchers/equipmentSwitch.vue";
import {
  equip_signal,
  equip_weather,
  equip_camera,
  equip_radar,
} from "../../dao/situation";

const EquipmentPopup = Vue.extend(equipmentPopup);
const VehiclePopup = Vue.extend(vehicleDetail);

import lightMixin from "../../mixin/lightMixin";

let map = null;
let vehiclePopups = {},
    popupVises = {},
    vehiclePopupInstances = {},
    licenseLabel = {}, // 车牌号label
    vehicleModels = {}, // 车辆model
    vehicleModelTypes = {},
    equipPopup = null,
    equipPopupInstance = null

export default {
  components: {
    GreenWave,
    CrossDetail,
    wMap,
    LayersSwitch,
    msgs,
    EquipmentSwitch,
  },
  mixins: [lightMixin],
  computed: {},
  data() {
    return {
      roadTimer: null,
      currentCheck: "first",
      timer: null,
      licenseState: false,
      lastLocation: [],
      bounds: [],
      sockets: [],
      selectVehicleTrackData: null,
      clickCrossData: {},
      isCrossDetail: false,
      loading: true,
      crossData: {id: "", name: ""},
      waveTitle: "",
      boxesShow: true,
      detailShow: false,
      dialogVisible: {
        crossDetailShow: false,
        greenWaveShow: false,
      },
      selectVehicle: {},
      greenId: "",
      layers: {
        first: [
          "crossStatus",
          "milliScope",
          "holo_crossPoint",
          "vehiclePic",
          "vehicle",
          "selectVehicleTrack",
          "vehicleSelectWave",
          "detetorsA",
          "detetorsB",
          "detetorsC",
          "lightLayer",
          "lightLayerText",
        ],
        second: ["holo_crossPointS", "vector_road_layer"],
        third: ["eventHeat", "eventPoint"],
        fourth: ["weather", "camera", "radar", "signal", "milli"],
      },
      crosses: null,
      crossGeo: null,
    };
  },
  watch: {
    // 根据左右两侧面板状态更新 mapbox-ctrl 组件样式
    boxesShow(val) {
      if (val) {
        document
            .getElementsByClassName("mapboxgl-ctrl-bottom-right")[0]
            .classList.remove("mapboxgl-ctrl-bottom-right-hide-box");
      } else {
        document
            .getElementsByClassName("mapboxgl-ctrl-bottom-right")[0]
            .classList.add("mapboxgl-ctrl-bottom-right-hide-box");
      }
    },
  },
  mounted() {
    let queue = [];
    let needDicts = [
      "CarColor",
      "CarType",
      "PlateColor",
      "EventType",
      "Direction",
    ];
    for (let item of needDicts) {
      queue.push(
          this.$store.dispatch("QUERY_DICT", {
            type: item,
          })
      );
    }
    Promise.all(queue).then(() => {
      map = this.$refs.wMap.initMap();
      map.on("style.load", () => {
        window.map = map
        this.loading = false;
        // 快捷键
        window.onkeydown = () => {
          // alt + 1/2 改变缩放层级
          if (event.altKey && (event.keyCode === 49 || event.keyCode === 97)) {
            map.flyTo({
              zoom: map_config.MAP_ZOOM,
              center: map_config.MAP_CENTER,
              bearing: map_config.MAP_BEARING,
              pitch: map_config.MAP_PITCH,
              duration: 1000,
              essential: true,
            });
            this.boxesShow = true;
          }
          if (event.altKey && (event.keyCode === 50 || event.keyCode === 98)) {
            map.flyTo({
              zoom: map_config.MAP_ZOOM2,
              center: map_config.MAP_CENTER2,
              bearing: map_config.MAP_BEARING2,
              pitch: map_config.MAP_PITCH2,
              duration: 1000, // Animate over 2 seconds
              essential: true,
            });
          }
          if (event.altKey && (event.keyCode === 51 || event.keyCode === 99)) {
            map.flyTo({
              zoom: map_config.MAP_ZOOM3,
              center: map_config.MAP_CENTER3,
              bearing: map_config.MAP_BEARING3,
              pitch: map_config.MAP_PITCH3,
              duration: 1000, // Animate over 2 seconds
              essential: true,
            });
          }
        };
        // 设置地图并加载必要资源
        this.refreshBounds();
        map.setFog({
          color: "#1d3244", // Lower atmosphere
          "high-color": "#030b19", // Upper atmosphere
          "horizon-blend": 0.2, // Atmosphere thickness (default 0.2 at low zooms)
          "space-color": "rgb(11, 11, 25)", // Background color
          "star-intensity": 0, // Background star brightness (default 0.35 at low zoooms )
        });
        for (let key in mapAssets.mapIcons) {
          if (map) {
            map.loadImage(mapAssets.mapIcons[key], (error, image) => {
              if (map && !map.hasImage(key)) map.addImage(key, image);
            });
          }
        }
        for (let key in mapAssets.lightIcons) {
          map.loadImage(mapAssets.lightIcons[key], (error, image) => {
            if (map && !map.hasImage(key)) map.addImage(key, image);
          });
        }
        ;
        window.tb = new Threebox(map, map.getCanvas().getContext("webgl"), {
          defaultLights: true,
          realSunlight: true,
          // realSunlightHelper: true,
          // sky: true,
          enableSelectingObjects: true,
        });
        map.addLayer({
          id: "vehicle3D",
          type: "custom",
          renderingMode: "3d",
          onAdd: (map, mbxContext) => {
            for (let item of this.$store.state.dicts.CarType) {
              let targetType = dict.carTypeGlbMap[item.code];
              let options = {
                obj: `gltf/car${targetType}.glb`,
                type: "gltf",
                units: "meters",
                scale: 0.8,
                adjustment: {x: 0.5, y: 1, z: -0.5},
                bbox: true,
              };
              window.tb.loadObj(options, (model) => {
                vehicleModelTypes[`car${item.code}`] = model;
              });
            }
            window.vehicleModelTypes = vehicleModelTypes;
          },
          render: function (gl, matrix) {
            window.tb.update();
          },
        });
        map.addControl(
            new mapboxgl.NavigationControl({showZoom: false}),
            "bottom-right"
        );
        map.on("dblclick", () => {
          console.log(
              "center " +
              map.getCenter() +
              " pitch " +
              map.getPitch() +
              " bearing " +
              map.getBearing() +
              " zoom " +
              map.getZoom()
          );
        });
        window.map = map;
        map.on("zoomend", () => {
          this.mapZoomEnd();

          this.refreshLightWs()
        });
        map.on("moveend", () => {
          this.mapZoomEnd();
          this.refreshLightWs()
        });
        this.switchfirst();
      });
    });
  },
  methods: {
    // 设备图例点击
    equipmentChange(equips) {
      for (let item of equips) {
        if (map.getLayer(item.label)) {
          map.setLayoutProperty(
              item.label,
              "visibility",
              item.check ? "visible" : "none"
          );
        }
      }
    },
    backToMain() {
      this.isCrossDetail = false;
      this.boxesShow = true;
      this.removeLayers("eventPoint1");
      map?.flyTo({
        duration: 1000,
        essential: true,
        bearing: map_config.MAP_BEARING,
        center: map_config.MAP_CENTER,
        zoom: map_config.MAP_ZOOM,
        pitch: map_config.MAP_PITCH,
      });
    },
    // 更新经纬度-角度-详细信息-弹窗信息
    setModel(model, options, setColor) {
      if (setColor) {
        model.traverse((child) => {
          if (child.isMesh && child.name.includes("_19")) {
            child.material = child.material.clone();
            let colorDesc = this.$store.state.dicts.CarColor.find((item) => {
              return item.code == options.originalColor;
            });
            let realColor = colorDesc
                ? dict.colorMatch[colorDesc.name]
                : "#fff";
            child.material.color.set(realColor);
          }
        });
      }
      model.setCoords([options.longitude, options.latitude]);
      model.setRotation({x: 90, y: 360 - options.courseAngle - 90, z: 0});
      model.userData.data = options;
    },
    clearLicense() {
      if (!this.licenseState) {
        for (let key in licenseLabel) {
          window.tb.clear(key, null);
        }
        licenseLabel = {};
      }
    },
    mapZoomEnd() {
      // 层级拉远自动清除事件点位 & 返回宏观图表视图
      if (map.getZoom() < 16.5) {
        this.isCrossDetail = false;
        this.removeLayers("eventPoint1");
      }
      this.refreshBounds();
    },
    refreshBounds() {
      let mapBounds = map.getBounds();
      let leftDownXy = [mapBounds._sw.lng, mapBounds._sw.lat];
      let rightUpXy = [mapBounds._ne.lng, mapBounds._ne.lat];
      let mid1 = [mapBounds._sw.lng, mapBounds._ne.lat];
      let mid2 = [mapBounds._ne.lng, mapBounds._sw.lat];
      this.bounds = [[leftDownXy, mid1, rightUpXy, mid2, leftDownXy]];
    },
    closeAllWs() {
      const closePromises = this.sockets.map((socket) => {
        return new Promise((resolve) => {
          if (socket.ws.readyState !== 1) {
            resolve();
          } else {
            socket.ws.onclose = () => {
              resolve();
            };
            socket.ws.close();
          }
        });
      });
      return Promise.all(closePromises).then(() => {
        for (let key in this.layers) {
          for (let layer of this.layers[key]) {
            this.removeLayers(layer);
          }
        }
        this.sockets = [];
      });
    },
    callCar(msg) {
      let zoom = map?.getZoom();
      // 车牌号状态
      if (!this.licenseState && Object.keys(licenseLabel).length) {
        for (let key in licenseLabel) {
          window.tb.clear(key, null);
        }
        licenseLabel = {};
      }
      // 筛选可见区域
      for (let i = 0; i < msg.length; i++) {
        if (
            !msg[i].picLicense ||
            dict.noVehicleTypes.includes(msg[i].originalType)
        ) {
          msg[i].picLicense = "";
        }
        let pt = turf.point([msg[i].longitude, msg[i].latitude]);
        let poly = turf.polygon(this.bounds);
        if (!turf.booleanPointInPolygon(pt, poly)) {
          msg.splice(i, 1);
          i = i - 1;
        }
      }
      if (msg.length > 0) {
        // 第一帧 || 时间戳不相同 => 放行
        if (
            this.lastLocation.length === 0 ||
            this.lastLocation[0].dateTime !== msg[0].dateTime
        ) {
          this.situationTimeVal = msg[0].dateTime;
          // zoom 大于 17 ： 移除圆点
          if (zoom >= 18) {
            this.removeLayers("vehiclePic,vehicle");
          }
          // zoom 小于 18：隐藏 threebox ；大于17且小于18的部分使用图片图层 其余部分使用圆点
          if (zoom < 18) {
            this.hideTb();
            let features = [];
            for (let item of msg) {
              features.push(turf.point([item.longitude, item.latitude], item));
            }
            let geo = turf.featureCollection(features);
            this.clearLicense();
            this.removeLayers(
                "vehicleSelectWave,license,licenseBack,vehiclePic"
            );
            mapTool.addOrUpdateVehicle(map, geo);
          }
          let allData = this.diff(this.lastLocation, msg);
          for (let item of allData) {
            // 如果选中车辆存在 则弹窗更新  否则删除弹窗
            if (this.selectVehicle && item.id === this.selectVehicle.id) {
              if (["add", "com"].includes(item.dill)) {
                if (popupVises[`popup${item.id}`]) {
                  this.addCheckDetail(item);
                }
              } else {
                this.removeLayers("vehicleSelectWave");
                this.removeVehiclePopup();
                this.clearSelectVehicle();
              }
            }
            if (zoom > 18) {
              // 新增
              if (this.modelsEmpty) {
                item.dill = "add";
                this.modelsEmpty = false;
              }
              if (
                  item.dill === "add" ||
                  (item.dill === "com" && !vehicleModels[item.id])
              ) {
                this.addVehicleModels(item);
                if (this.licenseState) this.addVehicleLicenses(item);
              } else {
                //   console.log("模型总数", Object.keys(vehicleModels).length);
                for (let key in vehicleModels) {
                  if (vehicleModels[key].userData.data?.id === item.id) {
                    if (item.dill === "del") {
                      if (licenseLabel[`license${item.id}`]) {
                        window.tb.clear(`license${item.id}`, true);
                        delete licenseLabel[`license${item.id}`];
                      }
                      if (vehicleModels[key]) {
                        window.tb.clear(item.id, true);
                        delete vehicleModels[key];
                      }
                    }
                    if (item.dill === "com") {
                      // 车型中途变化 清除并重新创建
                      if (
                          vehicleModels[key].userData.data.originalType !==
                          item.originalType
                      ) {
                        if (vehicleModels[key]) {
                          window.tb.clear(item.id, true);
                          delete vehicleModels[key];
                        }
                        if (licenseLabel[`license${item.id}`]) {
                          window.tb.clear(`license${item.id}`, true);
                          delete licenseLabel[`license${item.id}`];
                        }
                        this.addVehicleModels(item);
                        if (this.licenseState) this.addVehicleLicenses(item);
                      } else {
                        if (licenseLabel[`license${item.id}`]) {
                          // 如果车牌model存在且未改变 则setCoords
                          if (
                              licenseLabel[`license${item.id}`].userData.data
                                  .picLicense == item.picLicense
                          ) {
                            licenseLabel[`license${item.id}`].setCoords([
                              item.longitude,
                              item.latitude,
                              4,
                            ]);
                          }
                          // 否则先删除当前车牌 再创建更新后的车牌
                          else {
                            window.tb.clear(`license${item.id}`, true);
                            delete licenseLabel[`license${item.id}`];
                            this.addVehicleLicenses(item);
                          }
                        } else {
                          if (this.licenseState) this.addVehicleLicenses(item);
                        }
                        this.setModel(vehicleModels[key], item, true);
                      }
                    }
                  }
                }
              }
            }
          }
          this.lastLocation = msg;
        }
      }
    },
    hideTb() {
      if (window.tb) {
        for (let key in vehicleModels) {
          window.tb.clear(key, true);
        }
        for (let key in licenseLabel) {
          window.tb.clear(key, true);
        }
        window.tb.update();
        vehicleModels = {};
        this.lastLocation = [];
        this.showCameras = [];
        this.resetLightNearestCross()
        this.modelsEmpty = true;
      }
    },
    addVehicleModels(option) {
      if (vehicleModelTypes[`car${option.originalType}`]) {
        let model = vehicleModelTypes[`car${option.originalType}`].duplicate();
        this.setModel(model, option, true);
        model.addEventListener(
            "SelectedChange",
            this.onSelectedChangeVehicle,
            false
        );
        vehicleModels[option.id] = model;
        window.tb.add(model, option.id);
      }
    },
    // 选中模型改变
    onSelectedChangeVehicle(e) {
      if (e.detail.selected) {
        this.removeVehiclePopup();
        this.clearSelectVehicle();
        setTimeout(() => {
          this.selectVehicle = e.detail.userData.data;
          this.addCheckDetail(this.selectVehicle);
        }, 0);
      }
    },
    removeVehiclePopup() {
      console.log("do delete all Popups...");
      for (let key in vehiclePopups) {
        vehiclePopups[key]?.remove();
      }
      vehiclePopups = {};
      popupVises = {};
      vehiclePopupInstances = {};
    },
    // 清理选中车辆数据及其对应的轨迹
    clearSelectVehicle() {
      this.selectVehicleTrackData = null;
      this.removeLayers("selectVehicleTrack");
    },
    // 车辆详情弹窗内容
    addCheckDetail(data) {
      // console.log('haveThisPopup?',Boolean(vehiclePopups[`popup${data.id}`]),'thisPopupVises?',Boolean(popupVises[`popup${data.id}`]));
      if (vehiclePopups[`popup${data.id}`]) {
        if (popupVises[`popup${data.id}`]) {
          vehiclePopups[`popup${data.id}`].setLngLat([
            data.longitude,
            data.latitude,
          ]);
          vehiclePopupInstances[`popup${data.id}`].$props.model = data;
        }
        // 更新选中车辆的轨迹数据
        if (this.selectVehicleTrackData) {
          this.selectVehicleTrackData.lnglat.push([
            data.longitude,
            data.latitude,
          ]);
          this.updateSelectVehcleTrack();
        }
      } else {
        // 创建popup及初始化选中车辆轨迹
        this.selectVehicleTrackData = {
          lnglat: [[data.longitude, data.latitude]],
          properties: data,
        };
        vehiclePopups[`popup${data.id}`] = new mapboxgl.Popup({
          closeButton: true,
          anchor: "bottom",
          offset: [0, -20],
        });
        vehiclePopups[`popup${data.id}`]
            .setLngLat([data.longitude, data.latitude])
            .setHTML(`<div id="vehicle_popup${data.id}"></div>`)
            .addTo(map)
            .addClassName("vehicleDetailPopup");
        vehiclePopups[`popup${data.id}`].on("close", () => {
          vehiclePopups[`popup${data.id}`] = null;
          delete vehiclePopups[`popup${data.id}`];
          popupVises[`popup${data.id}`] = false;
          delete popupVises[`popup${data.id}`];
          this.clearSelectVehicle();
        });
        popupVises[`popup${data.id}`] = true;
        vehiclePopupInstances[`popup${data.id}`] = new VehiclePopup({
          propsData: {
            model: data,
          },
        });
        vehiclePopupInstances[`popup${data.id}`].$mount(
            `#vehicle_popup${data.id}`
        );
      }
    },
    // 转换轨迹数据为geo 并更新轨迹图层
    updateSelectVehcleTrack() {
      if (
          this.selectVehicleTrackData &&
          this.selectVehicleTrackData.lnglat.length > 1
      ) {
        let feature = turf.lineString(
            this.selectVehicleTrackData.lnglat,
            this.selectVehicleTrackData.properties
        );
        let geo = turf.featureCollection([feature]);
        mapTool.addOrUpdateSelectVehicleTrack(map, geo);
      }
    },
    addVehicleLicenses(option) {
      if (option.picLicense) {
        let ele = document.createElement("div");
        ele.style.color = "white";
        ele.innerText = option.picLicense;
        ele.style.backgroundImage = `url('${mapAssets.mapIcons[`license${option.licenseColor}`]
        }')`;
        ele.style.backgroundSize = "100% 100%";
        ele.style.fontSize = "8px";
        ele.style.textAlign = "center";
        ele.style.padding = "2px 4px 8px 4px";
        let license = window.tb.label({
          htmlElement: ele,
          alwaysVisible: true,
          topMargin: 2,
        });
        license.setCoords([option.longitude, option.latitude, 4]);
        license.userData.data = {picLicense: option.picLicense};
        window.tb.add(license, `license${option.id}`);
        licenseLabel[`license${option.id}`] = license;
      }
    },
    diff(oldData, newData) {
      // id 只在 newData 中存在且不在 oldData 中存在的即为 add
      const add = newData.filter((e) => !oldData.find((c) => c.id === e.id));
      // id 只在 oldData 中存在且不在 newData 中存在的即为 dele
      const del = oldData.filter((e) => !newData.find((c) => c.id === e.id));
      // common...
      const com = newData.filter((e) => oldData.find((c) => c.id === e.id));
      add.forEach((a) => (a.dill = "add"));
      del.forEach((d) => (d.dill = "del"));
      com.forEach((c) => (c.dill = "com"));
      return [...add, ...del, ...com];
    },
    openGreenWaveDialog(data) {
      this.dialogVisible.greenWaveShow = true;
      this.greenId = data.id;
      this.waveTitle = data.name;
    },
    showCrossStatus(data) {
      if (data) {
        this.crosses = data;
        let arr = data.map(item => {
          [item.longitude, item.latitude] = item.location
          return item
        })
        this.crossGeo = mapTool.convertPointsToGeo(arr)
      }
      if (this.crosses) {
        this.timer = setInterval(() => {
          if (
              map?.hasImage("crossStatus0") &&
              map?.hasImage("crossStatus1") &&
              map?.hasImage("crossStatus2") &&
              map?.hasImage("crossStatus3")
          ) {
            clearInterval(this.timer);
            let features = [];
            for (let item of this.crosses) {
              features.push(turf.point(item.location, item));
            }
            let geo = turf.featureCollection(features);
            mapTool.sAddOrUpdateCrossStatus(map, geo);
            map.on("click", "crossStatus", this.showRightDetail);
          }
        }, 100);
      }
    },
    showRightDetail(e) {
      console.log('cross click...', e.features[0]);
      let prop = e.features[0].properties;
      this.clickCrossData = prop;
      this.isCrossDetail = true;
      if (!Array.isArray(prop.location)) {
        prop.location = JSON.parse(prop.location);
      }
      map.flyTo({
        duration: 1000,
        essential: true,
        center: prop.location,
        zoom: 18.5,
      });
    },
    crossStatusClick(e) {
      this.openCrossIndexDetail(e.features[0].properties);
    },
    convertToPgWithWkt(json) {
      let features = [];
      for (let item of json) {
        if (item.wkt) {
          let lnglats = item.wkt.replaceAll(" ", "").split(";");
          for (let i = 0; i < lnglats.length; i++) {
            lnglats[i] = lnglats[i].split(",").map((j) => Number(j));
          }
          lnglats.pop();
          lnglats.push(lnglats[0]);
          features.push(turf.polygon([lnglats], item));
        }
      }
      return turf.featureCollection(features);
    },
    convertToLineWithWkt(json) {
      let features = [];
      for (let item of json) {
        if (item.wkt) {
          let lnglats = item.wkt.replaceAll(" ", "").split(";");
          for (let i = 0; i < lnglats.length; i++) {
            lnglats[i] = lnglats[i].split(",").map((j) => Number(j));
          }
          lnglats.pop();
          features.push(turf.lineString(lnglats, item));
        }
      }
      return turf.featureCollection(features);
    },
    removeLayers(names) {
      if (map) {
        for (let layerId of names.split(",")) {
          if (map.getLayer(layerId)) {
            map.removeLayer(layerId);
          }
          if (map.getSource(layerId)) {
            map.removeSource(layerId);
          }
        }
      }
    },
    showPolygon(data) {
      this.removeLayers("RoadPolygon,RoadLine");
      let polygon = this.convertToPgWithWkt([data]);
      let centerPoint = turf.center(polygon);
      let offsetPoint = turf.transformTranslate(centerPoint, 0.5, 180);
      mapTool.sAddOrUpdateRoadPolygon(map, polygon);
      mapTool.sAddOrUpdateRoadLine(map, this.convertToLineWithWkt([data]));
      map.flyTo({
        duration: 1000,
        essential: true,
        center: offsetPoint.geometry.coordinates,
        zoom: 16,
        bearing: map_config.MAP_BEARING,
        pitch: map_config.MAP_PITCH,
      });
    },
    openCrossIndexDetail(crossData) {
      this.showRightDetail({features: [{properties: crossData}]});
      // this.crossData = crossData
      // this.dialogVisible.crossDetailShow = true
    },
    actionFinished(id) {
      this.dialogVisible[id] = false;
    },
    switchfirst() {
      this.showCrossStatus();
      // 注册车辆实时ws
      let socket = initWs({
        name: "callCar",
        url: ws_config.BASE_URL,
        callback: this.callCar,
      });
      socket.ws.onopen = () => {
        if (socket.ws.readyState === 1) {
          socket.ws.send('{ dataType: "1"}');
          this.sockets.push(socket);
        }
      };
    },
    closeWs(name) {
      return new Promise((resolve) => {
        for (let key in this.sockets) {
          if (this.sockets[key].name === name) {
            this.sockets[key].ws.onclose = () => {
              this.sockets.splice(key, 1);
              resolve();
            };
            this.sockets[key].ws.close();
          }
        }
        resolve();
      });
    },
    switchsecond() {
      // 返回刷新定时器 供页面销毁
      this.roadTimer = mapTool.addOrUpdateRoadVector(map);
    },
    switchfourth() {
      Promise.all([
        equip_radar(),
        equip_signal(),
        equip_camera(),
        equip_weather(),
      ]).then(([radar, signal, camera, weather]) => {
        // console.log("设备。。。", radar, signal, camera, weather);
        let milliArray = [];
        let radarArray = [];
        for (let i = 0; i < radar.content.length; i++) {
          if (radar.content[i].sourceEquipType === "2") {
            milliArray.push(radar.content[i]);
          } else {
            radarArray.push(radar.content[i]);
          }
        }
        mapTool.addOrUpdateEquipMilli(map, milliArray);
        mapTool.addOrUpdateEquipRadar(map, radarArray);
        mapTool.addOrUpdateEquipSignal(map, signal.content);
        mapTool.addOrUpdateEquipCamera(map, camera.content);
        mapTool.addOrUpdateEquipWeather(map, weather.content);
        map.on("click", this.equipmentsClick);
      });
    },
    // 设备点击
    equipmentsClick(e) {
      event.stopPropagation();
      equipPopupInstance?.$destroy();
      equipPopupInstance = null;
      equipPopup = null;
      const features = map.queryRenderedFeatures(e.point, {
        layers: ["camera", "milli", "radar", "signal", "weather"],
      });
      if (features.length) {
        let prop = features[0].properties;
        let type = features[0].layer.id;
        if (prop.status == "1") {
          setTimeout(() => {
            // 创建新 popup 绑定事件（关闭时清除掉里面的video 防止占用资源）
            // 使用 Turf.js 进行平移计算
            let distance = 10; // 指定的平移距离（以米为单位）
            if (type === "signal") {
              //信号机popup窗口高度过高 加大偏移防止超出屏幕
              distance = 80;
            }
            let bearing = map.getBearing(); // 平移方向，0 表示正北方向
            let options = {units: "meters"};
            let translatedPoint = turf.destination(
                prop.wkt.split(","),
                distance,
                bearing,
                options
            );
            // 将地图中心点设置为平移后的点
            map.flyTo({
              center: translatedPoint.geometry.coordinates,
              zoom: 18,
            });
            equipPopup = new mapboxgl.Popup({
              anchor: "bottom",
              offset: [0, -20],
            });
            equipPopup
                .setLngLat(prop.wkt.split(","))
                .setHTML('<div id="equipment_popup"></div>')
                .addTo(map)
                .setMaxWidth("500")
                .addClassName("equipmentPopup");
            equipPopupInstance = new EquipmentPopup({
              propsData: {
                model: {equip_type: type, ...prop},
              },
            });
            equipPopupInstance.$mount("#equipment_popup");
            equipPopup?.on("close", () => {
              popupInstance?.$destroy();
              popupInstance = null;
              equipPopup = null;
            });
          }, 100);
        } else {
          ELEMENT.Message("设备已离线，请联系厂商");
        }
      }
    },
    changeCheck(beforeLabel, checkItem) {
      this.refreshBounds();
      map.flyTo({
        center: map_config.MAP_CENTER2,
        zoom: map_config.MAP_ZOOM2,
        bearing: map_config.MAP_BEARING2,
        pitch: map_config.MAP_PITCH2,
        duration: 1000,
        essential: true,
      })
      this.currentCheck = checkItem.label;
      if (beforeLabel === "first") {
        this.closeWs("callCar").then(() => {
          setTimeout(() => {
            this.removeLayers("vehicle,crossStatus");
            this[`switch${checkItem.label}`]();
            this.hideTb();
          }, 500);
        });
      } else {
        if (beforeLabel === "fourth") {
          equipPopup?.remove();
          map.off("click", this.equipmentsClick);
        }
        if (beforeLabel === 'second') {
          if (this.roadTimer) clearInterval(this.roadTimer)
        }
        for (let key in this.layers) {
          if (key !== checkItem.label) {
            for (let layer of this.layers[key]) {
              this.removeLayers(layer);
            }
          }
        }
        this[`switch${checkItem.label}`]();
      }
    },
    visibleChange() {
      this.boxesShow = !this.boxesShow;
    },
  },
  beforeDestroy() {
    if (this.roadTimer) clearInterval(this.roadTimer)
    this.timer && clearInterval(this.timer);
    this.closeAllWs()
    window.tb.dispose();
    window.tb = null;
    map = null;
    window.map = null;
  },
};
</script>
<style>
.mapboxgl-ctrl button.mapboxgl-ctrl-compass .mapboxgl-ctrl-icon {
  background-image: url("../../assets/images/holo/mapArrow.png") !important;
  background-size: 100% 100%;
}
</style>
<style lang="less" scoped>
.backToMain {
  cursor: pointer;
  position: absolute;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-image: url("../../assets/images/n_signal/backToMainImg.svg");
  right: 520px;
  width: 42px;
  height: 42px;
  font-size: 16px;
  letter-spacing: 10px;
  top: 5px;
  display: flex;
  align-items: center;
  padding-left: 10px;
  justify-content: center;
  z-index: 15;
  transition: 0.5s all ease;
}

.hideBackToMain {
  right: 20px;
  transition: 0.5s all ease;
}

.rightSwitch {
  left: 15px;
  top: 150px;
  transition: 0.5s all ease;
}

.generalSwitch {
  top: 150px;
  left: 535px;
  transition: 0.5s all ease;
}
</style>
