<template>
  <div ref="containerRef" class="map-container">
    <div
      id="aMap"
      class="map-container2"
      :style="{
        width: width,
        height: height,
        transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')',
        transformOrigin: '0 0'
      }"
    />
    <rightTool :mapState="mapState" type="AMap" :showMask="showMask" @changeShowMask="changeShowMask" />
  </div>
</template>

<script setup lang="ts" name="Map">
import rightTool from './rightTool.vue';
import { useAMap } from '@/hooks/AMap/useAMap';
import { useDrawTool } from '@/hooks/AMap/useDrawTool';
import { getPointInfoList } from '@/api/globalMap';
import { getDictLabel } from '@/utils/dict';
import { PointType } from '@/api/globalMap/type';
import {
  getEmergencyExpertDetails,
  getEmergencyShelterTypeDetails,
  getGasolinestationDetails,
  getHospitalDetails,
  getMiningcompanyDetails,
  getWarehouseDetails,
  getChemicalcompanyDetails,
  getSchoolDetails,
  getWaterloggedRoadsDetails,
  getShipRealtilmePositionDetails,
  getUAVDetails,
  getRainbowDetails,
  getTouristAttractionDetails,
  getConstructionSitesDetails,
  getYardSitesDetails,
  getStationInfoDetails,
  getMajorHazardSourceDetails,
  getBuildingProjectDetails,
  getChemicalWarehouseDetails,
  getMiningOperationsDetails,
  getEmergencyTransportResourcesDetails,
  getEmergencyDisasterInfoOfficerDetails,
  getMidmapDzzhDetails,
  getVehicleDetails,
  getMDPUnitDetails,
  getWaterList,
  getVideoDrowning,
  getVideoForestFire,
  getVideoDisasterPrevention
} from '@/api/globalMap/spatialAnalysis';
import { pointDetailTemplate } from '@/views/globalMap/data/mapData';
import useAppStore from '@/store/modules/app';
import { getRescueTeamsInfo } from '@/api/globalMap/rescueTeam';
import mmJson from '@/assets/json/mm2.json';
interface Props {
  activeMap: string;
  pointType: PointType[];
  showMask: boolean;
}

const containerScale = inject('containerScale');
const props = withDefaults(defineProps<Props>(), {});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { point_type } = toRefs<any>(proxy?.useDict('point_type'));
const appStore = useAppStore();

const emits = defineEmits([
  'update:drawing',
  'update:showMask',
  'selectGraphics',
  'unSelectGraphics',
  'showTextEditBox',
  'onDrawCompleted',
  'handleShowVideo',
  'handleShowWarehouse',
  'handleShowPeople'
]);
const containerRef = ref();
const width = ref('100%');
const height = ref('100%');

const mapState = reactive<MapState>({
  center: [110.925175, 21.978955],
  zoom: 8.5,
  minZoom: 6,
  maxZoom: 20,
  isThreeDimensional: false,
  // 是否显示比例尺
  showScale: true
});

let AMap, map, scale, placeSearch;

// 鼠标绘制工具
const drawTool = useDrawTool();
// 初始化地图
const mapUtils = useAMap({
  key: '9c5041381e5e824f9ee324d8f7a40150', // 申请好的Web端开发者Key，首次调用 load 时必填
  securityJsCode: '4868bc1b8fac7d9e54e7279ed556879a',
  version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
  pitch: mapState.isThreeDimensional ? 45 : 0,
  zoom: mapState.zoom,
  center: [mapState.center[0], mapState.center[1]],
  dragEnable: true,
  scrollWheel: true,
  showScale: true,
  enableMouseTool: true,
  // 加载完成事件
  onLoadCompleted: () => {
    AMap = getAMap();
    map = getMap();
    scale = getScale();
    if (!['logical', 'vectorgraph'].includes(props.activeMap)) {
      switchMap(props.activeMap);
    } else {
      map.removeLayer();
    }
    placeSearch = new AMap.PlaceSearch({
      pageSize: 30,
      pageIndex: 1,
      city: '0668',
      extensions: 'base'
    });
    map.on('zoomchange', zoomChangeHandler);
    // 添加遮罩
    if (props.showMask) {
      // creatMask2(mmJson, { strokeWeight: 2 });
      creatMask([{ strokeWeight: 2 }]);
    }
    drawTool.initMouseTool({ container: 'aMap', map, AMap });
    handleResize();
  },
  onMarkerClick: (data) => {
    // 多点位
    if (data.type === '1') {
      let path = [];
      props.pointType.forEach((item) => {
        path.push(item.component);
      });
      getPointInfoList({
        option: path.toString(),
        longitude: data.longitude.toString(),
        latitude: data.latitude.toString()
      }).then((res) => {
        const data2 = res.data.list;
        let content = document.createElement('div');
        // content.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
        content.className = 'point-info';
        let content2 = '';
        content2 += '<div class="title-box"><div class="gradient-text">多点位信息</div></div>';
        content2 += '<div class="icon1"></div>';
        content2 += '<div class="icon2"></div>';
        content2 += '<div class="icon3"></div>';
        content2 += '<div class="icon4"></div>';
        content.innerHTML = content2;
        let tableBox = document.createElement('div');
        tableBox.className = 'table-box';
        let table = document.createElement('div');
        table.className = 'table';
        table.innerHTML = '<div class="point-item"><div class="td3">主题</div><div class="td3">名称</div></div>';
        data2.forEach((item) => {
          item.longitude = data.longitude;
          item.latitude = data.latitude;
          const div = document.createElement('div');
          div.className = 'point-item point-item-hover';
          div.innerHTML =
            '<div class="td4">' + getDictLabel(point_type.value, item.dataType.toString()) + '</div><div class="td4">' + item.name + '</div>';
          div.addEventListener('click', () => {
            handlePointDetails(item);
          });
          table.appendChild(div);
        });
        tableBox.appendChild(table);
        content.appendChild(tableBox);
        let closeBtn = document.createElement('div');
        closeBtn.className = 'close';
        closeBtn.onclick = hideInfo;
        content.appendChild(closeBtn);
        showInfo(content, [data.longitude, data.latitude], true);
      });
    } else {
      handlePointDetails(data);
    }
  }
});
const {
  getAMap,
  getMap,
  switchMap,
  addMarker,
  addSearchMarker,
  clearMarker,
  getMarkers,
  getScale,
  showInfo,
  hideInfo,
  handleHover,
  creatMask,
  creatMask2,
  removeMask,
  trackPlayback
} = { ...mapUtils };
const handlePointDetails = (data) => {
  let methodList = {
    '1': getEmergencyExpertDetails,
    '2': getWarehouseDetails,
    '3': getEmergencyShelterTypeDetails,
    '4': getWaterloggedRoadsDetails,
    '5': getSchoolDetails,
    '6': getHospitalDetails,
    '7': getGasolinestationDetails,
    '8': getMiningcompanyDetails,
    // '9': getChemicalcompanyDetails,
    '10': getShipRealtilmePositionDetails,
    '11': getChemicalcompanyDetails,
    '12': getChemicalcompanyDetails,
    '13': getChemicalcompanyDetails,
    '14': getChemicalcompanyDetails,
    '15': getUAVDetails,
    '16': getRainbowDetails,
    '17': getMidmapDzzhDetails,
    '18': getMiningOperationsDetails,
    '20': getMDPUnitDetails,
    '21': getBuildingProjectDetails,
    '22': getChemicalWarehouseDetails,
    '23': getMajorHazardSourceDetails,
    '24': getStationInfoDetails,
    '25': getYardSitesDetails,
    '26': getTouristAttractionDetails,
    '27': getConstructionSitesDetails,
    '28': getEmergencyTransportResourcesDetails,
    '29': getEmergencyDisasterInfoOfficerDetails,
    '30': getVehicleDetails,
    '31': getWaterList,
    '32': getVideoDrowning,
    '33': getVideoForestFire,
    '34': getVideoDisasterPrevention,
    '41': getRescueTeamsInfo
  };
  let titleList = {
    '1': '专家信息',
    '2': '物资与装备仓库信息',
    '3': '避难所信息',
    '4': '易涝点信息',
    '5': '学校信息',
    '6': '医院信息',
    '7': '加油站信息',
    '8': '非煤矿山企业信息',
    '9': '危化企业信息',
    '10': '船舶动态信息',
    '11': '危险化学品经营企业信息',
    '12': '危险化学品生产企业信息',
    '13': '危险化学品使用企业(使用许可)信息',
    '14': '化工企业(不发使用许可)信息',
    '15': '无人机信息',
    '16': '雨窝点',
    '17': '地质灾害隐患点',
    '18': '矿山施工',
    '19': '工矿商贸',
    '20': '气象灾害防御重点单位',
    '21': '建筑工程',
    '22': '储罐信息',
    '23': '重大危险源',
    '24': '客运站',
    '25': '堆场',
    '26': '旅游场所',
    '27': '在建工地',
    '28': '运输资源',
    '29': '灾害信息员',
    '30': '重点车辆信息',
    '31': '江湖河库',
    '32': '防溺水',
    '33': '森林防火',
    '34': '防灾救援',
    '41': '救援队伍'
  };
  let method = methodList[data.dataType];
  let title = !!titleList[data.dataType] ? titleList[data.dataType] : '信息';
  if (!method) return;
  method(data.id).then((res) => {
    if (!!pointDetailTemplate[data.dataType]) {
      let div = document.createElement('div');
      // div.style.cssText = 'transform: scale(' + containerScale().scaleX + ');';
      div.className = 'point-info';
      let titleDom = document.createElement('div');
      titleDom.className = 'title-box';
      titleDom.innerHTML = '<div class="gradient-text">' + title + '</div></div>';
      div.appendChild(titleDom);
      if (data.dataType === 2) {
        let btnBox = document.createElement('div');
        let btn = document.createElement('div');
        btnBox.className = 'flex';
        btn.className = 'btn';
        btn.innerHTML = '<div class="video-icon"></div><div>物资详情</div>';
        btn.onclick = () => {
          emits('handleShowWarehouse', data);
        };
        btnBox.appendChild(btn);
        div.appendChild(btnBox);
      } else if (data.dataType === 4) {
        let btnBox = document.createElement('div');
        let btn = document.createElement('div');
        btnBox.className = 'flex';
        btn.className = 'btn';
        btn.innerHTML = '<div class="video-icon"></div><div>附近视频</div>';
        btn.onclick = () => {
          emits('handleShowVideo', data);
        };
        btnBox.appendChild(btn);
        div.appendChild(btnBox);
      } else if (data.dataType === 41) {
        let btnBox = document.createElement('div');
        let btn = document.createElement('div');
        btnBox.className = 'flex';
        btn.className = 'btn';
        btn.innerHTML = '<div class="video-icon"></div><div>人员列表</div>';
        btn.onclick = () => {
          emits('handleShowPeople', data);
        };
        btnBox.appendChild(btn);
        div.appendChild(btnBox);
      }
      let icon1 = document.createElement('div');
      icon1.className = 'icon1';
      let icon2 = document.createElement('div');
      icon2.className = 'icon2';
      let icon3 = document.createElement('div');
      icon3.className = 'icon3';
      let icon4 = document.createElement('div');
      icon4.className = 'icon4';
      div.appendChild(icon1);
      div.appendChild(icon2);
      div.appendChild(icon3);
      div.appendChild(icon4);
      let table = document.createElement('div');
      table.className = 'table-box';
      let content = '';
      content += '<div class="table">';
      const newData = filterTd(res.rows[0], data.dataType);
      newData.forEach((item) => {
        if (item.type === 'shortText') {
          content += '<div class="tr">';
          item.data.forEach((item2) => {
            content += '<div class="point-item">';
            content += '<div class="td1">' + item2.label + '</div><div class="td2">' + item2.value + '</div>';
            content += '</div>';
          });
          content += '</div>';
        } else {
          content += '<div class="point-item2">';
          content += '<div class="td1">' + item.data[0].label + '</div><div class="td2">' + item.data[0].value + '</div>';
          content += '</div>';
        }
      });
      content += '</div>';
      table.innerHTML = content;
      div.appendChild(table);
      let closeBtn = document.createElement('div');
      closeBtn.className = 'close';
      closeBtn.onclick = hideInfo;
      div.appendChild(closeBtn);
      showInfo(div, [data.longitude, data.latitude], true);
    }
  });
};
const filterTd = (obj, dataType) => {
  let data = [];
  let tempData = {};
  let i = 0;
  for (let key in obj) {
    let keyLabel = pointDetailTemplate[dataType][key];
    if (!!keyLabel) {
      if (i === 2) {
        i = 0;
      }
      const value = !!obj[key] ? obj[key] : '';
      if (value && value.length > 8) {
        if (i === 0) {
          data.push({ type: 'longText', data: [{ label: keyLabel, value: value }] });
          i = 0;
        } else {
          tempData = { type: 'longText', data: [{ label: keyLabel, value: value }] };
        }
      } else {
        if (i === 0) {
          data.push({ type: 'shortText', data: [{ label: keyLabel, value: value }] });
        } else {
          data[data.length - 1].data.push({ label: keyLabel, value: value });
        }
        i++;
        if (!!tempData && JSON.stringify(tempData) !== '{}') {
          data.push(tempData);
          tempData = {};
          i = 0;
        }
      }
    }
  }
  if (!!tempData && JSON.stringify(tempData) !== '{}') {
    data.push(tempData);
  }
  if (data[data.length - 1].data && data[data.length - 1].data.length === 1 && data[data.length - 1].type === 'shortText') {
    data[data.length - 1].data[1] = { label: '', value: '' };
  }
  return data;
};
// 监听地图类型变化
watch(
  () => props.activeMap,
  (value, oldValue) => {
    switchMap(props.activeMap);
  }
);
watch(
  () => props.showMask,
  () => {
    if (props.showMask) {
      creatMask([{ strokeWeight: 2 }]);
    } else {
      removeMask();
    }
  }
);
// watc h(
//   () => props.mouseToolState,
//   () => {
//     if (props.drawing) {
//       drawGraphics(props.mouseToolState);
//     } else {
//       closeDraw();
//     }
//   },
//   {
//     deep: true
//   }
// );
// 缩放级别变化
const zoomChangeHandler = () => {
  mapState.zoom = map.getZoom();
};

const setCenter = (item) => {
  map.setCenter([item.longitude, item.latitude]);
};

const getMapUtils = () => {
  return mapUtils;
};
const getPlaceSearch = () => {
  return placeSearch;
};

let inverseScale = ref({
  inverseScaleX: 1,
  inverseScaleY: 1
});
const handleResize = () => {
  inverseScale.value.inverseScaleX = 1 / containerScale().scaleX;
  inverseScale.value.inverseScaleY = 1 / containerScale().scaleY;
  const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
  const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
  width.value = containerWidth + 'px';
  height.value = containerHeight + 'px';
  map.resize();
};

const changeShowMask = () => {
  emits('update:showMask', !props.showMask);
};
watch(
  () => appStore.showLeftSection,
  () => {
    nextTick(() => {
      handleResize();
    });
  }
);
watch(
  () => appStore.showRightSection,
  () => {
    nextTick(() => {
      handleResize();
    });
  }
);
onMounted(() => {
  window.addEventListener('resize', handleResize);
});
// 卸载事件
onUnmounted(() => {
  if (map) {
    map.off('zoomchange', zoomChangeHandler);
  }
  window.removeEventListener('resize', handleResize);
});

provide('getMap', getMap);
provide('getScale', getScale);
defineExpose({
  addMarker,
  addSearchMarker,
  setCenter,
  getMarkers,
  clearMarker,
  getMap,
  drawTool,
  handleHover,
  trackPlayback,
  getMapUtils,
  getPlaceSearch
});
</script>

<style lang="scss" scoped>
@import 'map.scss';
.map-container2 {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
.map-container {
  width: 100%;
  height: 100%;
  :deep(.amap-scalecontrol) {
    left: unset !important;
    background-color: unset !important;
    right: 56px;
    bottom: 17px !important;
  }
  :deep(.amap-scale-text) {
    text-align: left !important;
    padding-left: 20px;
    color: #eaf3fc;
    font-size: vw(32);
    font-family: 'SourceHanSansCN';
  }
  :deep(.amap-scale-edgeleft),
  :deep(.amap-scale-middle),
  :deep(.amap-scale-edgeright) {
    border: 1px solid #bfe1fc !important;
    background: transparent !important;
  }
  :deep(.amap-logo),
  :deep(.amap-copyright) {
    display: none !important;
  }
  /* 自定义测距工具样式 */
  :deep(.amap-ranger) {
    background-color: #ffffff;
    border: 1px solid #888888;
    border-radius: 5px;
    padding: 5px;
  }

  :deep(.amap-ranger .amap-toolbar) {
    color: #333;
    font-size: 12px;
    padding: 5px;
  }

  :deep(.amap-ranger .amap-toolbar button) {
    background-color: #022577;
    color: #fff;
    border: none;
    border-radius: 4px;
    padding: 5px;
    margin-right: 5px;
    cursor: pointer;
  }

  :deep(.amap-ranger .amap-toolbar button:hover) {
    background-color: #1a3c75;
  }

  :deep(.amap-ranger .amap-toolbar .amap-toolbar-text) {
    color: #444;
    font-size: 14px;
  }
  :deep(.amap-marker) {
    font-size: 16px;
  }
  :deep(.amap-marker-label) {
    border: 1px solid #474747;
    background-color: rgba(255, 255, 255, 0.65);
    padding: 3px 8px;
    border-radius: 4px;
  }
}
</style>
