<template>
  <div class="easy-map" v-bind="$attrs">
    <OlMap
      ref="ref_olMap"
      :baseMapLayers="baseMapLayersCpt"
      :baseMapView="baseMapViewCpt"
      @olZoomChange="(zoom) => $emit('zoomChange', zoom)"
      @olMapLoad="(map) => handleOlMapLoad(map)"
      :layout="layout"
    />
    <template v-if="drawEditsConfig.show">
      <div class="draw-edits-config">
        <div class="draw-edits-config_feature-type">
          <el-select v-model="drawEditsConfig.featureType" @change="drawEditsSwitchFeatureType">
            <el-option label="点" value="Point" :disabled="!drawEditsConfig.isPoint"/>
            <el-option label="线" value="LineString" :disabled="!drawEditsConfig.isLineString"/>
            <el-option label="多边形" value="Polygon" :disabled="!drawEditsConfig.isPolygon"/>
          </el-select>
        </div>
        <div class="draw-edits-config_position __hover">
          <el-popover
              width="500px"
              placement="top"
              title="经纬度"
              trigger="click"
              v-model:visible="drawEditsConfig.showPosition"
          >
            <div class="popover">
              <CusForm ref="ref_drawEditsForm" labelWidth="0">
                <CusFormColumn
                    ref="ref_drawEditsWkt"
                    required
                    :span="24"
                    type="textarea"
                    :rows="4"
                    v-model:param="drawEditsConfig.wkt"
                    :placeholder="drawEditsWktPlaceholderCpt"
                    :rules="[
                      {
                        handle: (val) => drawEditsConfig.featureType !== 'Point' || (drawEditsConfig.featureType === 'Point' && $easyMap.validWkt.Point(val)),
                        message: '点位WKT坐标格式错误'
                      },
                      {
                        handle: (val) => drawEditsConfig.featureType !== 'LineString' || (drawEditsConfig.featureType === 'LineString' && $easyMap.validWkt.LineString(val)),
                        message: '线段WKT坐标格式错误'
                      },
                      {
                        handle: (val) => drawEditsConfig.featureType !== 'Polygon' || (drawEditsConfig.featureType === 'Polygon' && $easyMap.validWkt.Polygon(val)),
                        message: '区域WKT坐标格式错误'
                      },
                      {
                        handle: (val) => drawEditsConfig.featureType !== 'Polygon' || (drawEditsConfig.featureType === 'Polygon' && $easyMap.validWkt.PolygonKinks(val)),
                        message: '区域坐标不可自相交'
                      },
                    ]"
                />
              </CusForm>

<!--              <el-input-->
<!--                  v-model="drawEditsConfig.wkt"-->
<!--                  type="textarea"-->
<!--                  :rows="4"-->
<!--                  placeholder="请输入经纬度"-->
<!--              ></el-input>-->
              <div class="footer">
                <el-button size="small" type="primary" @click="changeWkt">保存</el-button>
                <el-button size="small" @click="drawEditsConfig.showPosition = false">取消</el-button>
              </div>
            </div>
            <template #reference>
              <div class="reference">
                <img src="./images/draw-edits-position.png" alt />
                <span>经纬度</span>
              </div>
            </template>
          </el-popover>
        </div>
        <template v-if="drawEditsConfig.featureType === 'Point'">
          <div class="draw-edits-config_icon">
            <img v-if="drawEditsConfig.pointIcon" class="icon" :src="drawEditsConfig.pointIcon"/>
            <div class="text"><CusEllipsis :value="drawEditsConfig.text || '点位'"/></div>
          </div>
        </template>
        <template v-if="drawEditsConfig.featureType === 'LineString'">
          <div class="draw-edits-config_split"/>
          <div class="draw-edits-config_line">
            <div class="text">线段</div>
            <el-input-number
                class="width"
                v-model="drawEditsConfig.lineWidth"
                :min="1"
                :max="100"
                controls-position="right"
                step-strictly
                @change="drawEditsConfig.refreshStyleFunc()"
            />
            <el-color-picker v-model="drawEditsConfig.lineColor" show-alpha @change="drawEditsConfig.refreshStyleFunc()"/>
            <el-select class="type" v-model="drawEditsConfig.lineType" @change="drawEditsConfig.refreshStyleFunc()">
              <el-option label="—————" :value="0"/>
              <el-option label="— — — —" :value="1"/>
              <el-option label="- - - - - -  - -" :value="2"/>
            </el-select>
          </div>
        </template>
        <template v-if="drawEditsConfig.featureType === 'Polygon'">
          <div class="draw-edits-config_split"/>
          <div class="draw-edits-config_line">
            <div class="text">边框</div>
            <el-input-number
                class="width"
                v-model="drawEditsConfig.polyBorderWidth"
                :min="1"
                :max="100"
                controls-position="right"
                step-strictly
                @change="drawEditsConfig.refreshStyleFunc()"
            />
            <el-color-picker v-model="drawEditsConfig.polyBorderColor" show-alpha @change="drawEditsConfig.refreshStyleFunc()"/>
            <el-select class="type" v-model="drawEditsConfig.polyBorderType" @change="drawEditsConfig.refreshStyleFunc()">
              <el-option label="—————" :value="0"/>
              <el-option label="— — — —" :value="1"/>
              <el-option label="- - - - - -  - -" :value="2"/>
            </el-select>
          </div>
          <div class="draw-edits-config_split"/>
          <div class="draw-edits-config_poly">
            <div class="text">填充</div>
            <el-color-picker v-model="drawEditsConfig.polyColor" show-alpha @change="drawEditsConfig.refreshStyleFunc()"/>
          </div>
        </template>
      </div>
    </template>
    <div class="base-switch">
      <el-popover
          placement="left"
          trigger="hover"
          popper-class="easy-map-base-switch"
      >
        <template #reference>
          <div style="width: 200px; height: 200px; background-color: red;"/>
        </template>
        <div class="base-switch-item" v-if="ref_olMap">
          <template v-for="[k, v] in ref_olMap.baseLayersMap">
            <div
                class="base-item __hover"
                :class="{active: judgeBaseLayerActive(k)}"
                @click="ref_olMap.switchBaseLayer(k)"
            >
              <div class="label">{{ v.get("_label") }}</div>
              <img :src="v.get('_img')" />
            </div>
          </template>
        </div>
      </el-popover>
    </div>
  </div>
  <ToolsLocationCom v-model:show="toolsShow.location" :mapFuncToLocation="toLocation"/>
</template>

<script lang="ts">
import {
  defineComponent,
  onMounted,
  ref,
  toRefs,
  reactive,
  watch,
  getCurrentInstance,
  ComponentInternalInstance,
  computed,
  nextTick,
} from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import OlMap from "./ol-map.vue";
import InitMapInfoClass from "./initMapInfo";
import MeasureFunc from "./func/measure";
import DrawFunc, {DrawClear} from "./func/draw";
import LocationFunc from "./func/location";
import ToolsLocationCom from './component/tools/tools-location.vue'
import * as BaseDraw from './func/base-draw'
import {ElMessage, ElMessageBox} from "element-plus";

export default defineComponent({
  name: "EasyMap",
  components: {
    OlMap,
    ToolsLocationCom
  },
  props: {
    baseMapLayers: {},
    baseMapView: {},
    layout: {}
  },
  emits: ['easyMapLoad', 'zoomChange'],
  setup(props, { emit }) {
    const store = useStore();
    const router = useRouter();
    const that = (getCurrentInstance() as ComponentInternalInstance).appContext
      .config.globalProperties;
    const state = reactive({
      toolsShow: {
        location: false,
      },
      drawEditsConfig: BaseDraw.getBaseDrawConfig()
    });

    const ref_olMap = ref();
    const baseMapLayersCpt = computed(
      () => props.baseMapLayers || InitMapInfoClass.baseMapLayers
    );
    const baseMapViewCpt = computed(
      () => props.baseMapView || InitMapInfoClass.baseMapView
    );
    const easyMap = computed(() => ref_olMap.value?.easyMapOl);
    const handleOlMapLoad = (map) => {
      emit("easyMapLoad", map, {
        getBBOX,
        measure,
        draw,
        drawClear,
        toLocation,
        baseLayer: {
          switchMapper: ref_olMap.value.baseLayersMap,
          switchLayer: ref_olMap.value.switchBaseLayer,
          judgeActive: judgeBaseLayerActive,
        },
        drawViews,
        drawEdits
      });
    };
    const getBBOX = () => {
      return easyMap.value.getView().calculateExtent(easyMap.value.getSize());
    };
    const judgeBaseLayerActive = (layerName) => {
      return easyMap.value
        ?.getLayers()
        .getArray()
        .filter((v) => v.get("_easyMapOl_layerGroupType") === "base")[0]
        .getLayers()
        .getArray()
        .filter((v) => v.get("_easyMapOl_layerName") === layerName)[0]
        ?.getVisible();
    };
    const measure = (type) => {
      MeasureFunc(easyMap.value, type);
    };
    const draw = (type) => {
      return new Promise((resolve, reject) => {
        DrawFunc(easyMap.value, type).then(res => {
          resolve(res)
        }).catch((msg) => {
          reject(msg)
        });
      })
    };
    const drawClear = () => {
      DrawClear(easyMap.value);
    };
    const toLocation = ({ position = null, zoom = null, wkt = null }) => {
      LocationFunc({
        map: easyMap.value,
        position,
        wkt,
        zoom,
      });
    };
    const drawViews = (arr: any) => {
      BaseDraw.drawViews(easyMap.value, arr)
    }
    const drawEdits = (obj: any, emitFunc) => {
      state.drawEditsConfig = Object.assign(BaseDraw.getBaseDrawConfig(), obj, {
        emitFunc
      })
      setTimeout(() => {
        state.drawEditsConfig.show = true
        if (state.drawEditsConfig.featureType === 'Point') {
          state.drawEditsConfig.isPoint = true
        } else if (state.drawEditsConfig.featureType === 'LineString') {
          state.drawEditsConfig.isLineString = true
        } else if (state.drawEditsConfig.featureType === 'Polygon') {
          state.drawEditsConfig.isPolygon = true
        }
        BaseDraw.drawEdits(easyMap.value, state.drawEditsConfig, (wkt) => {
          state.drawEditsConfig.wkt = wkt
          emitFunc(state.drawEditsConfig)
        }).then((func: any) => {
          state.drawEditsConfig.refreshStyleFunc = () => {
            func()
            emitFunc(state.drawEditsConfig)
          }
        })
      })
    }
    const drawEditsSwitchFeatureType = (val) => {
      state.drawEditsConfig.wkt = null
      state.drawEditsConfig.featureType = val
      drawEdits(state.drawEditsConfig, state.drawEditsConfig.emitFunc)
    }
    const ref_drawEditsForm = ref();
    const changeWkt = () => {
      //  缺少wkt格式校验
      ref_drawEditsForm.value.submit().then(() => {
        drawEdits(state.drawEditsConfig, state.drawEditsConfig.emitFunc)
      }).catch((e) => {
        ElMessage({
          message: e[0].message,
          grouping: true,
          type: 'warning',
        })
      })
    }
    const drawEditsWktPlaceholderCpt = computed(() => {
      let str = ''
      if (state.drawEditsConfig.featureType === 'Point') {
        str = '请输入点位WKT格式坐标，例：POINT(109.1 20.5)'
      } else if (state.drawEditsConfig.featureType === 'LineString') {
        str = '请输入线段WKT格式坐标，例：LINESTRING(109.2 19.5,109.6 19.1,110.2 19.4)'
      } else if (state.drawEditsConfig.featureType === 'Polygon') {
        str = '请输入区域WKT格式坐标，例：POLYGON((109.7 19.3,109.5 19.1,109.8 19.1,109.7 19.3))'
      }
      return str
    })
    onMounted(() => {
      nextTick(() => {});
    });
    return {
      ...toRefs(state),
      ref_olMap,
      baseMapLayersCpt,
      baseMapViewCpt,
      easyMap,
      getBBOX,
      measure,
      draw,
      toLocation,
      handleOlMapLoad,
      judgeBaseLayerActive,
      drawEditsSwitchFeatureType,
      changeWkt,
      ref_drawEditsForm,
      drawEditsWktPlaceholderCpt
    };
  },
});
</script>
<style scoped lang="scss">
.easy-map {
  width: 100%;
  height: 100%;
  position: relative;
  .draw-edits-config {
    height: 54px;
    position: absolute;
    left: 0;
    bottom: 0;
    z-index: 2000;
    background-color: #fff;
    display: flex;
    align-items: center;
    font-size: 14px;
    padding: 0 10px;
    border-top-right-radius: 6px;
    $mR: 10px;
    .draw-edits-config_feature-type {
      width: 90px;
    }
    .draw-edits-config_position {
      border: 1px solid #eee;
      border-radius: 25px;
      padding: 5px 15px;
      margin-left: $mR;
      color: #255fef;
      display: flex;
      align-items: center;
      justify-content: center;
      .reference {
        width: 70px;
        display: flex;
        align-items: center;
        justify-content: space-around;
      }
    }
    .draw-edits-config_icon {
      border: 1px solid #eee;
      border-radius: 25px;
      padding: 5px 15px;
      color: #255fef;
      margin-left: $mR;
      display: flex;
      align-items: center;
      justify-content: center;
      .icon {
        margin-right: 6px;
        width: 20px;
        height: 20px;
      }
      .text {
        max-width: 100px;
      }
    }
    .draw-edits-config_split {
      background-color: #eee;
      margin: 0 $mR;
      width: 1px;
      height: 100%;
    }
    .draw-edits-config_line, .draw-edits-config_poly {
      display: flex;
      align-items: center;
      .text {
        font-size: 14px;
        color: #333333;
        word-break: keep-all;
        margin-right: $mR;
      }
      .width {
        width: 80px;
        margin-right: $mR;
      }
      .type {
        width: 94px;
        margin-left: $mR;
      }
    }
  }
}


.base-switch {
  position: absolute;
  top: 0;
  right: 0;
}
</style>
