<template>
  <div id="globalMap">
    <div class="global-map">
      <Map
        v-if="mapStore.isAMap"
        ref="mapRef"
        @handle-show-video="handleShowVideo"
        @handle-show-video-detail="handleShowVideo2"
        @handle-show-warehouse="handleShowWarehouse"
        @handle-show-people="handleShowPeople"
        @handle-show-track="handleShowTrack"
        @close-detail-dialog="handleCloseDetailDialog"
        @resize="mapMoveEnd"
      />
      <YztMap
        v-else-if="!!mapStore.activeMap"
        ref="map2Ref"
        @handle-show-video="handleShowVideo"
        @handle-show-video-detail="handleShowVideo2"
        @handle-show-warehouse="handleShowWarehouse"
        @handle-show-people="handleShowPeople"
        @handle-show-track="handleShowTrack"
        @close-detail-dialog="handleCloseDetailDialog"
        @resize="mapMoveEnd"
      />
      <!--左侧菜单-->
      <LeftMenu
        ref="leftMenuRef"
        style="position: absolute; top: 20px; left: 20px"
        @click-menu="clickMenu"
        @select-search-marker="selectSearchMarker"
      />
      <!--右侧功能模块-->
      <RightMenu ref="rightMenuRef" />
      <!--切换地图图层-->
      <SwitchMapTool class="tool-box" />
      <!--右下角地图工具 -->
      <RightTool />
      <!--时间轴-->
      <TimeAxis ref="timeAxisRef" />
      <!--绘制工具-->
      <DrawTools v-if="showDrawTools" @handle-analysis-data="handleAnalysisData" />
      <!--附近视频-->
      <NearbyVideos v-if="showNearbyVideos" v-model="showNearbyVideos" :location="location" />
      <!--格点雨量-->
      <GridPointRainfall v-if="showRainfall" v-model="showRainfall" :location="location" />
      <!--物资详情-->
      <MaterialDetail v-if="showWarehouse" v-model="showWarehouse" :warehouse-data="warehouseData" />
      <!--通讯保障-->
      <CommunicationSupport v-if="communicationSupport.show" @close="handleHideCommunicationSupport" />
      <!--应急人员详情-->
      <EmergencyCrew v-if="showPeople" v-model="showPeople" :id="teamId" />
      <!--视频详情-->
      <VideoDialog v-if="showVideoDetail" v-model="showVideoDetail" :videoMonitorData="videoDetail" @close="handleVideoDetailClose" />
    </div>
  </div>
</template>

<script lang="ts" setup name="globalMap">
import Map from '@/components/Map/index.vue';
import YztMap from '@/components/Map/YztMap/index.vue';
import SwitchMapTool from './SwitchMapTool.vue';
import LeftMenu from './LeftMenu.vue';
import RightMenu from './RightMenu/index.vue';
import MaterialDetail from './MaterialDetail.vue';
import TimeAxis from '@/components/TimeAxis/index.vue';
import DrawTools from './RightMenu/DrawTools.vue';
import CommunicationSupport from './RightMenu/CommunicationSupport.vue';
import GridPointRainfall from './RightMenu/GridPointRainfall.vue';
import EmergencyCrew from './RightMenu/EmergencyCrew.vue';
import useMapStore from '@/store/modules/map';
import { getVehicleTrajectory } from '@/api/globalMap/KeyVehicles';
import { getImageUrl, iconList } from './data/mapData';
import { debounce, deepClone } from '@/utils';
import { parseTime } from '@/utils/ruoyi';
import { getPointInfo2 } from '@/api/videoMonitor';
import { toLonLat } from 'ol/proj';
import { getEventDetail } from '@/api/duty/eventing';
import gcoord from 'gcoord';

//dom元素
const rightMenuRef = ref(null);
const mapRef = ref(null);
const map2Ref = ref(null);
const leftMenuRef = ref(null);
const timeAxisRef = ref(null);
const route = useRoute();
const eventId = ref('');

// 地图
let map: any = {};
// 地图类
let mapUtils: any = {};
const mapStore = useMapStore();
// 附近视频菜单数据
let tempMenu = ref({
  name: '',
  checked: false
});
const communicationSupport = reactive({
  show: false,
  data: {}
});
let addMarkersTimer;
// 添加打点
const addMarkers = (item) => {
  const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  if (dom) {
    if (!item.checked) {
      let index = mapStore.pointType.findIndex((item2) => item.component === item2.component);
      if (index > -1) {
        mapStore.pointType.splice(index, 1);
      }
    } else {
      // 右侧图层分析状态
      item.checked2 = true;
      mapStore.pointType.push(item);
    }
    mapStore.setPointOption();
  }
};
const adjustPoint = (data) => {
  data.forEach((item2) => {
    // 获取图标
    if (iconList[item2.dataType]) {
      item2.icon = iconList[item2.dataType].image;
      item2.image = iconList[item2.dataType].image;
      item2.imageHover = iconList[item2.dataType].imageHover;
      item2.size = iconList[item2.dataType].size;
    } else {
      item2.icon = iconList['common'].image;
      item2.image = iconList['common'].image;
      item2.imageHover = iconList['common'].imageHover;
      item2.size = iconList['common'].size;
    }
    if (item2.materia_name) {
      item2.name = item2.materia_name;
    }
    if (item2.dataType === 43) {
      item2.showName = true;
    }
    item2.lnglat = [item2.longitude, item2.latitude];
  });
  return data;
};

const addMarkersMethod = debounce(
  function () {
    if (!mapUtils || Object.keys(mapUtils).length === 0) return;
    const queryParams: PointParams = {
      zoom_level: mapStore.mapState.zoom,
      latitude_min: '',
      latitude_max: '',
      longitude_min: '',
      longitude_max: '',
      option: mapStore.pointParams.option,
      dict_value: mapStore.pointParams.dict_value.toString()
    };
    if (!queryParams.option && !queryParams.dict_value) {
      return mapUtils.clearMarker2();
    }
    if (mapStore.isAMap) {
      const AMap = mapUtils.getAMap();
      const pixel = new AMap.Pixel(0, 0);
      const size = mapRef.value.getMapDomSize();
      const pixel2 = new AMap.Pixel(size[0], size[1]);
      const lnglat = map.containerToLngLat(pixel);
      const lnglat2 = map.containerToLngLat(pixel2);
      queryParams.longitude_min = lnglat.lng;
      queryParams.latitude_max = lnglat.lat;
      queryParams.longitude_max = lnglat2.lng;
      queryParams.latitude_min = lnglat2.lat;
    } else {
      // 获取地图容器尺寸
      const size = map.getSize();
      // 获取左上角和右下角像素坐标
      const topLeftPixel = [0, 0];
      const bottomRightPixel = [size[0], size[1]];
      // 转换为地图投影坐标
      const topLeftMap = map.getCoordinateFromPixel(topLeftPixel);
      const bottomRightMap = map.getCoordinateFromPixel(bottomRightPixel);
      // 转换为经纬度
      const lnglat = toLonLat(topLeftMap, map.getView().getProjection());
      const lnglat2 = toLonLat(bottomRightMap, map.getView().getProjection());
      queryParams.longitude_min = lnglat[0];
      queryParams.latitude_max = lnglat[1];
      queryParams.longitude_max = lnglat2[0];
      queryParams.latitude_min = lnglat2[1];
    }
    getPointInfo2(queryParams).then((res) => {
      // 如果接口返回前，取消所有选择，不赋值
      if (!mapStore.pointParams.option && !mapStore.pointParams.dict_value.toString()) {
        return;
      }
      const data = res.data ? res.data : [];
      // 通用详情
      console.log(detailsData.value.id);
      if (!!detailsData.value.id) {
        data.forEach((item) => {
          if (item.id === detailsData.value.id) {
            item.isHover = true;
          } else if (showVideoDetail.value && videoDetail.value) {
            data.forEach((item) => {
              if (item.id === videoDetail.value.id) {
                item.isHover = true;
              }
            });
          }
        });
        // detailsData.value = {
        //   id: '',
        //   dataType: ''
        // };
      }
      mapUtils.addMarker2(data);
    });
    if (addMarkersTimer) {
      clearInterval(addMarkersTimer);
      addMarkersTimer = null;
    }
    if (mapStore.pointParams.option.includes('43')) {
      addMarkersTimer = setInterval(addMarkersMethod, 60 * 1000);
    }
  },
  300,
  false
);
// 跳转指定地点
const toAddress = (item) => {
  const dom = mapStore.activeMap === 'imageMap' ? map2Ref.value : mapRef.value;
  dom.setCenter(item);
};

let showDrawTools = ref(false);

// 点击菜单
const clickMenu = (item, dataList) => {
  if (item.path === '1') {
    // 空间分析
    if (item.component === 'spatial') {
      showDrawTools.value = !showDrawTools.value;
    }
    if (item.component && item.component !== 'spatial') {
      // 打点信息
      addMarkers(item);
    }
    rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item);
  } else if (item.path === '2') {
    if (item.name === '附近视频') {
      // 附近视频
      tempMenu.value = item;
      //为地图注册click事件获取鼠标点击出的经纬度坐标
      map.on('click', handleClickMap);
      mapStore.setIsMapSelect(true);
    } else {
      let checked = item.checked ? '1' : '2';
      if (item.component) {
        // 打点信息
        addMarkers(item);
      }
      if (item.isVideo) {
        rightMenuRef.value.updateMenu(checked, item);
      } else {
        let index = findChecked(dataList, item.name);
        if (item.checked && index > 0) {
          // 已有图层分析直接切换到该index
          rightMenuRef.value.showIndexMenu('图层分析');
        } else if (item.checked || (!item.checked && index === 0)) {
          rightMenuRef.value.updateMenu(checked, { name: '图层分析', meta: { icon: 'icon1' } });
        }
      }
    }
  } else if (item.path === '3') {
    // 通讯保障
    communicationSupport.show = !communicationSupport.show;
    communicationSupport.data = item;
  } else if (item.path === '4' && ['定点分析', '格点雨量'].includes(item.name)) {
    if (item.name === '定点分析' && !item.checked) {
      closeClickMap();
      rightMenuRef.value.updateMenu('2', item, []);
    } else {
      // 定点分析、格点雨量
      tempMenu.value = item;
      //为地图注册click事件获取鼠标点击出的经纬度坐标
      map.on('click', handleClickMap);
      mapStore.setIsMapSelect(true);
    }
  }
  // 菜单关闭，移除车辆
  if (['手机工作台', '重点车辆', '移动指挥车', '机动无人机', '卫星电话'].includes(item.name) && !item.checked) {
    timeAxisRef.value.clearData(item.name);
  }
  if (item.component == '43' && !item.checked && !mapStore.pointParams.option.includes('43') && addMarkersTimer) {
    clearInterval(addMarkersTimer);
    addMarkersTimer = null;
  }
};
const handleHideCommunicationSupport = () => {
  communicationSupport.show = false;
  leftMenuRef.value.setMenuChange(communicationSupport.data, false);
};
const findChecked = (dataList, name) => {
  let index = 0;
  dataList.forEach((item) => {
    if (
      !['易涝隐患点', '省政务无人机', '铁塔运行监测', '通讯保障', '救援队伍', '重点车辆', '附近视频', '河道监测', '水库监测'].includes(item.name) &&
      item.name !== name &&
      !item.isVideo &&
      item.path === '2' &&
      !!item.checked
    ) {
      index++;
    }
    if (item.children && item.children.length > 0) {
      let res = findChecked(item.children, name);
      index += res;
    }
  });
  return index;
};
// 点击搜索结果，添加标注
const selectSearchMarker = (item) => {
  const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  let item2 = deepClone(item);
  // 获取图标
  if (iconList[item2.dataType]) {
    item2.icon = iconList[item2.dataType].imageHover;
    item2.image = iconList[item2.dataType].image;
    item2.imageHover = iconList[item2.dataType].imageHover;
    item2.size = iconList[item2.dataType].size;
  } else {
    item2.icon = iconList['common'].imageHover;
    item2.image = iconList['common'].image;
    item2.imageHover = iconList['common'].imageHover;
    item2.size = iconList['common'].size;
  }
  item2.lnglat = [item2.longitude, item2.latitude];
  dom.addSearchMarker(item2);
};
const handleAnalysisData = (data) => {
  rightMenuRef.value.handleMenu('空间分析', data);
};
const getMapUtils = () => {
  const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  return !!domRef ? domRef.getMapUtils() : {};
};
// 获取地图元素操作
const getMap = () => {
  const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  return !!domRef ? domRef.getMap() : {};
};
let detailsData = ref({
  id: '',
  dataType: ''
});
//  显示打点详情
const showDetail = (data, dataType) => {
  const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  if (!!domRef) {
    const newMap = mapStore.isAMap ? map : map.getView();
    newMap.setCenter([data.lng, data.lat]);
    newMap.setZoom(18);
    detailsData.value = {
      id: data.id.toString(),
      dataType: dataType
    };
  }
};
const getDrawTool = () => {
  return mapStore.isAMap ? mapRef.value.drawTool : mapUtils;
};
const trackPlayback = (data) => {
  const domRef = mapStore.isAMap ? mapRef.value : mapUtils;
  if (!!domRef) {
    domRef.trackPlayback(data);
  }
};
let showNearbyVideos = ref(false);
let showRainfall = ref(false);
let location = ref([]);
watch(showNearbyVideos, () => {
  if (!!showNearbyVideos.value) {
    closeClickMap();
  } else {
    clearData();
  }
});
watch(showRainfall, () => {
  if (!!showRainfall.value) {
    closeClickMap();
  } else {
    clearData();
  }
});
const clearData = () => {
  location.value = [];
  if (!!tempMenu.value && !!tempMenu.value.name) {
    leftMenuRef.value.setMenuChange(tempMenu.value, false);
    tempMenu.value = {
      name: '',
      checked: false
    };
  }
};
const closeClickMap = () => {
  if (mapStore.isAMap) {
    map.off('click', handleClickMap);
  } else {
    map.un('click', handleClickMap);
  }
  mapStore.setIsMapSelect(false);
};
// 显示附近视频
const handleShowVideo = (data) => {
  location.value = [data.longitude, data.latitude];
  showNearbyVideos.value = true;
};
const showVideoDetail = ref(false);
const videoDetail = ref({});
const handleShowVideo2 = (data, flag) => {
  const newMap = mapStore.isAMap ? map : map.getView();
  if (!flag) {
    newMap.setCenter([data.longitude, data.latitude]);
    newMap.setZoom(18);
  }
  videoDetail.value = data;
  showVideoDetail.value = true;
};
const handleVideoDetailClose = () => {
  videoDetail.value = [];
  mapUtils.clearHoverMarker();
};
const handleClickMap = (e) => {
  if (mapStore.isAMap) {
    location.value = [e.lnglat.lng, e.lnglat.lat];
  } else {
    location.value = e.coordinate;
  }
  if (!!tempMenu.value && tempMenu.value.name === '附近视频') {
    showNearbyVideos.value = true;
  } else if (!!tempMenu.value && tempMenu.value.name === '格点雨量') {
    showRainfall.value = true;
  } else if (!!tempMenu.value && tempMenu.value.name === '定点分析') {
    const item = deepClone(tempMenu.value);
    const nowLocation = deepClone(location.value);
    tempMenu.value = {
      name: '',
      checked: false
    };
    if (mapStore.isAMap) {
      map.off('click', handleClickMap);
    } else {
      map.un('click', handleClickMap);
    }
    mapStore.setIsMapSelect(false);
    rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item, nowLocation);
  }
};
let showWarehouse = ref(false);
let warehouseData = ref('');
const handleShowWarehouse = (data) => {
  warehouseData.value = data;
  showWarehouse.value = true;
};

// 救援队伍人员列表
let showPeople = ref(false);
let teamId = ref('');
const handleShowPeople = (data) => {
  teamId.value = data.id;
  showPeople.value = true;
};

watch(
  () => mapStore.trackState.show,
  (show) => {
    if (!!show) {
      const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
      dom?.addMarker(adjustPoint(mapStore.trackState.data));
      mapStore.trackState.data = [];
      mapStore.trackState.show = false;
    }
  }
);
const handleShowTrack = (data) => {
  getVehicleTrajectory(data.id).then((res) => {
    const trajectory = [];
    if (res.data && res.data.list) {
      res.data.list.forEach((item) => {
        trajectory.push({
          time: !!item.gpsDate ? parseTime(item.gpsDate, '{h}:{i}') : '',
          lnglat: [item.lng, item.lat]
        });
      });
      initDataToPlay({ id: data.id, type: 'track', data: trajectory, name: data.title }, true);
    }
  });
};
// 传递数据给时间轴
const initDataToPlay = (data, isDetail?: boolean) => {
  if (!!timeAxisRef.value) {
    timeAxisRef.value.initDataToPlay(data, isDetail);
  }
};
// 点位详情弹窗关闭后
const handleCloseDetailDialog = (data) => {
  timeAxisRef.value.clearData(data.title, true);
};
const mapMoveEnd = () => {
  if (!mapStore.pointParams.dict_value && !mapStore.pointParams.option) return;
  addMarkersMethod();
};
watch(
  () => mapStore.mapLoaded,
  (loaded) => {
    if (loaded) {
      map = getMap();
      mapUtils = getMapUtils();
      if (!!map && Object.keys(map).length !== 0) {
        map.on('moveend', mapMoveEnd);
      }
      if (eventId.value) {
        getEventDetail({ event_id: eventId.value }).then((res) => {
          const lnglat = gcoord.transform([res.data.longitude, res.data.latitude], gcoord.GCJ02, gcoord.WGS84);
          const newMap = mapStore.isAMap ? map : map.getView();
          newMap.setCenter(lnglat);
          mapUtils.setAddress({
            longitude: lnglat[0],
            latitude: lnglat[1],
            image: getImageUrl('address.png'),
            imageHover: getImageUrl('address_hover.png'),
            size: [45, 48],
            name: '灾害地点'
          });
        });
      }
    }
  },
  {
    immediate: true
  }
);
watch(
  () => mapStore.updateAddress,
  (lnglat) => {
    if (lnglat && lnglat.length == 2) {
      const newMap = mapStore.isAMap ? map : map.getView();
      newMap.setCenter(lnglat);
      mapUtils.setAddress({
        longitude: lnglat[0],
        latitude: lnglat[1],
        image: getImageUrl('address.png'),
        imageHover: getImageUrl('address_hover.png'),
        size: [45, 48],
        name: '灾害地点'
      });
    }
  }
);
// 监听视频打点
watch(
  () => mapStore.pointParams,
  () => {
    if (mapStore.updateMenu && !!mapStore.updateMenu.name) {
      // 视频修改的值，需要显示左侧辅助分析、显示右侧菜单
      leftMenuRef.value.setMenuIndex(2);
      // rightMenuRef.value.updateMenu('1', mapStore.updateMenu);
      mapStore.setUpdateMenu({});
    }
    addMarkersMethod();
  },
  {
    deep: true
  }
);
// 监听层级变化
watch(
  () => mapStore.mapState.zoom,
  () => {
    mapMoveEnd();
  },
  {
    deep: true
  }
);
onMounted(() => {
  mapStore.initData();
  eventId.value = route.query.event_id;
});
onBeforeUnmount(() => {
   if (!!map && Object.keys(map).length !== 0) {
    if (mapStore.isAMap) {
      map.off('click', handleClickMap);
      map.off('moveend', handleClickMap);
    } else {
      map.un('click', handleClickMap);
      map.un('moveend', handleClickMap);
    }
    mapStore.setIsMapSelect(false);
  }
  if (!!addMarkersTimer) {
    clearInterval(addMarkersTimer);
    addMarkersTimer = null;
  }
});

provide('getMapUtils', getMapUtils);
provide('getMap', getMap);
provide('trackPlayback', trackPlayback);
provide('showDetail', showDetail);
provide('getDrawTool', getDrawTool);
provide('initDataToPlay', initDataToPlay);
provide('handleShowVideo2', handleShowVideo2);
</script>

<style lang="scss" scoped>
#globalMap {
  width: 100%;
  height: 100%;
}
.global-map {
  width: 100%;
  height: 100%;
  position: relative;
  //overflow: hidden;
  .tool-box {
    position: absolute;
    right: 85px;
    bottom: 90px;
    z-index: 10;
    color: #fff;
  }
}
.box {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 300px;
  background-color: #041d55;
  display: flex;
  flex-direction: column;
  padding: 20px;
  color: #fff;
  font-size: 16px;
  height: 500px;
  max-height: 90%;
  div {
    line-height: 30px;
    cursor: pointer;
  }
}
.fixed {
  position: fixed !important;
}
</style>
