<template>
    <div class="map-container">
      <div id="mapContainer" class="map-box"></div>
  
      <!-- 图层控制 -->
      <div class="layer-control-center">
        <p v-for="(item, index) in props.layers">
          <a-checkbox v-model:checked="item.checked" @change="handlerCheckboxChange(item)">{{
            item.name
          }}</a-checkbox>
        </p>
      </div>
  
      <!-- 绘图控制 -->
      <div class="draw-control-center" v-show="drawing">
        <div class="draw-btn" @click="handlerCancleDraw"> 取消 </div>
        <div class="draw-btn" @click="handlerDrawComplete"> 保存 </div>
      </div>
    </div>
  </template>
  
  <script lang="ts" setup>
    import {
      onMounted,
      onUnmounted,
      defineProps,
      defineEmits,
      reactive,
      ref,
      defineExpose,
    } from 'vue';

    import { useMessage } from '@/hooks/web/useMessage';

    import mapboxgl, { Map, Popup } from 'mapbox-gl';
  
    // 图形绘制工具类
    import MapboxDraw from '@mapbox/mapbox-gl-draw';
  
    import U from 'mapbox-gl-utils';
    import 'mapbox-gl/dist/mapbox-gl.css';
    import './src/index.less';
    import { MapboxConfig, MapboxDefaultStyle, MapControlConfig } from './src/config';
    import { MP } from './src/MP';
    import { DrawingType } from '@/enums/mapEnum';
  
    import {
      SnapPolygonMode,
      SnapPointMode,
      SnapLineMode,
      SnapModeDrawStyles,
      SnapDirectSelect,
    } from 'mapbox-gl-draw-snap-mode';
  
    import { customDrawStyles } from './Styles/Styles';
    import Drawtool from '@/views/datamaintenance/components/drawtool.vue';
    import { WktToGeojson, GeojsonToWkt } from './src/WktGeojsonTransform';
    import { features } from 'process';
  
    const openModal = ref(false);
    const insertShpModal = ref(false);
    const changeOpenModal = (value) => {
      openModal.value = value;
    };
    const changeOpenInsertShpModal = (value) => {
      insertShpModal.value = value;
    };
  
    // map参数类型
    interface MapboxOptionsInterface {
      mapOptions: mapboxgl.MapboxOptions;
      control: DrawingType[];
    }
  
    const props = defineProps({
      layers: {
        type: Array,
        default: [],
      },
      location: {
        type: Array,
        default: [],
      },
      type: {
        type: String,
        default: '',
      },
      feature: {
        type: String,
        default: '',
      },
    });
  
    let nextMapControl: Array<any> = reactive([]);
    nextMapControl = props.control
      ? props.control.map((item) => {
          return MapControlConfig[item];
        })
      : [];
  
    // 定义地图容器
    let map: Map;
    let drawTool: any;
    let popup: Popup;
    let clickPoisition: Array<number> = [];
    let selectFeature: Object = {};
    let mp: any = null;
    let geojson = reactive({
      geojson: {},
    });
    let drawing = ref(false);
  
    let drawGeojson = reactive({
      geojson: {
        type: 'FeatureCollection',
        features: [],
      },
    });
  
    const { createConfirm, createMessage } = useMessage();
  
    // 定义地图回调emit
    // 地图加载完成回调
    const emit = defineEmits(['mapOnLoad', 'mapDraw', 'handlerDrawComplete']);
  
    onMounted(() => {
      mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
      map = initMap();
      map.on('load', () => {
        // 初始化绘图空间
        // handlerInitDrawTool(null);
  
        map.on('click', (e) => {
          // handlerPreviewFeatureInfo(e);
          clickPoisition = e.lngLat;
        });
  
        map.on('draw.selectionchange', (e) => {
          // handlerCopyToTargetLayer(e);
        });
        emit('mapOnLoad', map);
  
        // 设置绘图监听事件
        map.on('draw.create', function (e) {
          drawGeojson.geojson.features = e.features;
          handlerDealFeature(e.features[0]);
        });
  
        map.on('draw.update', function (e) {
          drawGeojson.geojson = e.features;
          handlerDealFeature(e.features[0]);
        });
  
        map.on('draw.delete', function (e) {
          handlerDeleteFeature(e.features[0]);
        });
  
        window.handlerCopyFeature = handlerCopyFeature;
      });
    });
    // 销毁地图
    // 移除地图实例
    onUnmounted(() => {
      map ? map.remove() : null;
    });
  
    // 数据绘制完成判断
    const handlerDealFeature = (feature) => {
      let existFeature = geojson.geojson.features.find((item, index) => {
        return item.id == feature.id;
      });
  
      if (existFeature) {
        // 如果查找到了 则替换数据
        for (let i = 0; i < geojson.geojson.features.length; i++) {
          if (geojson.geojson.features[i].id == feature.id) {
            geojson.geojson.features[i] = feature;
          }
        }
      } else {
        // 如果没找到数据 则添加到数组
        geojson.geojson.features.push(feature);
      }
      // handlerDrawComplete();
    };
  
    // 删除数据
    const handlerDeleteFeature = (feature) => {
      for (let i = 0; i < geojson.geojson.features.length; i++) {
        if (geojson.geojson.features[i].id == feature.id) {
          geojson.geojson.features.splice(i, 1);
        }
      }
      // handlerDrawComplete();
    };
  
    // 初始化地图 返回地图实例
    const initMap = () => {
      return new mapboxgl.Map({
        container: 'mapContainer',
        language: 'zh-cmn',
        projection: 'equirectangular', // wgs84参考系
        style: MapboxDefaultStyle,
        maxZoom: 22,
        minZoom: 6,
        zoom: 14,
        center: props.location,
      });
    };
  
    const handlerMapControlClick = (handler: string) => {
      handler === 'handlerDrawPoint' && handlerDrawPoint();
      handler === 'handlerDrawLineString' && handlerDrawLineString();
      handler === 'handlerDrawPolygon' && handlerDrawPolygon();
    };
    //绘制点
    const handlerDrawPoint = () => {
      mp.draw('Point');
      mp.on('Point', function (e) {
        emit('mapDraw', 'Point', e);
      });
    };
    //绘制线
    const handlerDrawLineString = () => {
      mp.draw('LineString');
      mp.on('LineString', function (e) {
        emit('mapDraw', 'LineString', e);
      });
    };
    //绘制面
    const handlerDrawPolygon = () => {
      mp.draw('Polygon');
      mp.on('Polygon', function (e) {
        emit('mapDraw', 'Polygon', e);
      });
    };
    //删除标记
    const handlerUnDraw = () => {
      mp.deleteDraw();
      emit('mapDraw', 'cancel');
    };
  
    // 初始化绘图空间
    const handlerInitDrawTool = (feature, bool) => {
      if (feature.features.length > 0) {
        feature.features.forEach((item) => {
          if (item.geometry.type == 'MultiPolygon') {
            let arr: any = ref([]);
            item.geometry.coordinates.forEach((val) => {
              arr.value.push(val[0]);
            });
            item.geometry.coordinates = arr.value;
            item.geometry.type = 'Polygon';
          }
        });
      }
  
      geojson.geojson = feature;
      console.log('drawTool', drawTool);
      console.log('feature', feature);
      if (drawTool) {
        drawTool.deleteAll();
        if (feature.features) {
          drawTool.set(geojson.geojson);
        }
      } else {
        drawTool = new MapboxDraw({
          modes: {
            ...MapboxDraw.modes,
            draw_point: SnapPointMode,
            draw_polygon: SnapPolygonMode,
            draw_line_string: SnapLineMode,
            direct_select: SnapDirectSelect,
          },
          styles: customDrawStyles,
          userProperties: true,
          snap: true,
          snapOptions: {
            snapPx: 12, // defaults to 15
            snapToMidPoints: true, // defaults to false
            snapVertexPriorityDistance: 0.0025, // defaults to 1.25
          },
          guides: false,
        });
        map.addControl(drawTool, 'top-right');
        if (feature.features) {
          drawTool.set(geojson.geojson);
        }
      }
      // 正在绘制
      if (bool) {
        drawing.value = true;
      } else {
        drawing.value = false;
      }
    };
  
    // 将图斑复制到指定图层
    const handlerCopyToTargetLayer = (e) => {
      if (e.features.length > 0) {
        if (popup) {
          popup.remove();
          popup = null;
        }
  
        selectFeature = e.features[0];
  
        popup = new mapboxgl.Popup({
          closeButton: false,
          closeOnClick: false,
        });
  
        // 设置 popup 的位置和内容
        popup
          .setLngLat(clickPoisition)
          .setHTML(
            `
                    <div style="color:#333;padding:3px 12px;cursor:pointer;" type="primary" icon="el-icon-search" onclick="handlerCopyFeature();">复制当前图斑</div>`,
          )
          .addTo(map);
      } else {
        popup.remove();
      }
    };
  
    const handlerCopyFeature = () => {
      popup.remove();
      createMessage.success('复制成功！');
    };
  
    // 添加到图层
    const handlerAddToLayerList = (layer) => {
      handlerCheckLayerExist(layer);
    };
  
    // 判断图层列表中是否一定添加
    const handlerCheckLayerExist = (layer) => {
      for (let i = 0; i < layerList.length; i++) {
        if (layerList[i] == layer.id) {
          return;
        }
      }
      layerList.push(layer);
    };
  
    const handlerCheckboxChange = (item) => {
      handlerPreviewLayer(item);
    };
  
    // 控制图层是否显示
    const handlerPreviewLayer = (layer) => {
      handlerLayerControler(layer);
    };
  
    // 图层控制中心
    const handlerLayerControler = (layerInfo) => {
      if (map.getSource(layerInfo.layer.id)) {
        if (layerInfo.checked) {
          map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'visible');
        } else {
          map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'none');
        }
      } else {
        map.addLayer(layerInfo.layer);
        map.on('click', layerInfo.layer.id, function (e) {
          handlerPreviewFeatureInfo(e);
        });
      }
    };
  
    // 查看列表数据
    const handlerDataList = () => {};
  
    // 图斑属性查看
    const handlerPreviewFeatureInfo = (e) => {
      if (e.features) {
        isOpen.value = true;
      }
    };
  
    const handlerClose = (e) => {
      isOpen.value = e;
    };
  
    // 图斑定位
    const handlerLocation = (lngLat) => {
      map.flyTo({
        center: lngLat,
        zoom: 16,
        speed: 10, // 飞行速度
        curve: 1, // 飞行曲线
        easing(t) {
          // 飞行动画函数
          return t;
        },
      });
    };
  
    // 编辑图斑
    const handlerEdit = (info) => {
      initDraw(info);
    };
  
    const initDraw = (layerInfo) => {

      // 实例化绘图工具
      drawTool = new MapboxDraw({
        modes: {
          ...MapboxDraw.modes,
          draw_point: SnapPointMode,
          // draw_polygon: SnapPolygonMode,
          // draw_line_string: SnapLineMode,
          direct_select: SnapDirectSelect,
        },
        styles: customDrawStyles,
        userProperties: true,
        snap: true,
        snapOptions: {
          snapPx: 15, // defaults to 15
          snapToMidPoints: true, // defaults to false
          snapVertexPriorityDistance: 0.0025, // defaults to 1.25
        },
        guides: false,
      });
  
      map.addControl(drawTool, 'top-right');
  
      // let geojson:Object = {};
      // if (layerInfo.dataType == "面") {
      //     geojson.type = "Polygon";
      //     geojson.coordinates = geojson.coordinates[0];
      // } else if (layerInfo.dataType == "点") {
      //     geojson.type = "Point";
      //     geojson.coordinates = geojson.coordinates;
      // } else if (layerInfo.dataType == "线") {
      //   geojson.type = "LineString";
      //   geojson.coordinates = geojson.coordinates[0];
      // }
      // if (formData.lat && formData.lng) {
      //   formData.lat = geojson.coordinates[1];
      //   formData.lng = geojson.coordinates[0];
      // }
      // geojson = {
      //   type: "FeatureCollection",
      //   features: [
      //     {
      //       type: "Feature",
      //       geometry: geojson,
      //     },
      //   ],
      // };
      // map.setLayoutProperty("pbfLayer", "visibility", "none");
      // drawTool.set(geojson);
    };
  
    const handlerDrawComplete = () => {
      let arr = [];
      geojson.geojson.features.forEach((item, index) => {
        let wktStr = GeojsonToWkt(item.geometry);
        let obj = {
          columnName: 'mapgeom',
          value: wktStr,
        };
        arr.push(obj);
      });
      console.log('aaaa', arr);
      emit('handlerDrawComplete', arr);
    };
  
    const handlerCancleDraw = () => {
      map.removeControl(drawTool);
      drawTool = null;
      drawing.value = false;
      // drawTool.set(geojson.geojson)
    };
  
    const handlerDraw = (features = null, bool = false) => {
    
      console.log("features",features);
      
      let geo = {
        type: 'FeatureCollection',
        features: [],
      };

      console.log('features', features);
      console.log('bool', bool);
      
      if (features == null) {
        bool = true;
      } else {
        if (features.length > 0) {
          for (let i = 0; i < features.length; i++) {

            try {
                
              let featureTemp = WktToGeojson(features[i].value);

              let feature = {
                id: 'cd1d93c0e4a6747ff597f' + parseInt(1000000000 * Math.random()).toString(),
                type: 'Feature',
                properties: {},
                geometry: featureTemp,
              };

              geo.features.push(feature);

            } catch (e) {
              console.log('WKT解析错误，请检查WKT数据格式是否有误');
            }
          }
        }
      }
      handlerInitDrawTool(geo, bool);
    };
  
    defineExpose({
      handlerDraw,
      handlerLocation,
      handlerCancleDraw,
    });
  </script>
  
  <style>
    .map-container {
      width: 100%;
      height: 100%;
    }
    .map-box {
      width: 100%;
      height: 100%;
    }
    .layer-control-center {
      position: absolute;
      padding: 10px;
      top: 15px;
      left: 15px;
      background: #ffffff;
      border-radius: 12px;
    }
    .layer-control-center p {
      margin: 0px;
    }
    .draw-control-center {
      position: absolute;
      padding: 7px;
      top: 15px;
      right: 15px;
      background: #ffffff;
      border-radius: 12px;
    }
    .draw-control-center .draw-btn {
      float: left;
      margin: 0px 6px;
      padding: 5px;
      border-radius: 5px;
    }
  
    .draw-control-center .draw-btn:hover {
      background-color: rgb(0 0 0/5%);
      cursor: pointer;
    }
    .mapboxgl-ctrl-group:not(:empty) {
      box-shadow: none;
    }
    .mapboxgl-ctrl-group {
      padding: 10px;
      border-radius: 12px;
      position: relative;
      right: 140px;
      top: 5px;
    }
    .mapbox-gl-draw_ctrl-draw-btn {
      width: 20px !important;
      height: 20px !important;
      float: left;
    }
    .mapboxgl-ctrl-top-right {
    }
  
    .mapboxgl-ctrl-group button + button {
      border: 0px;
      margin: 0px 10px;
    }
  
    .mapbox-gl-draw_ctrl-draw-btn:hover {
      transform: scale(1.2);
    }
    .mapbox-gl-draw_polygon {
      background-image: url(/polygon.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
    }
    .mapbox-gl-draw_point {
      background-image: url(/point.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
    }
    .mapbox-gl-draw_line {
      background-image: url(/line.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
      margin: 0px 10px;
    }
  
    .mapbox-gl-draw_trash {
      background-image: url(/del.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
    }
  
    .mapbox-gl-draw_combine {
      background-image: url(/combine.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
    }
  
    .mapbox-gl-draw_uncombine {
      background-image: url(/uncombine.png);
      background-size: 100% 100%;
      width: 100px;
      height: 100px;
    }
  </style>
  