<template>
  <div class="box" :class="props.config.showTitle ? 'pt-10' : ''">
    <div class="item-title" v-if="props.config.showTitle">{{ props.title }}</div>
    <div ref="chartRef" class="item" :id="conId"> </div>
  </div>
</template>

<script setup lang="ts">
  import { nextTick, onMounted, ref, unref, watch } from 'vue';
  import { MapProperties } from '../config/properties';
  import { DesktopComponent } from '/@/enums/desktop';
  import { MapConfig, PanelArrangeTypeEnum, PanelTitleTypeEnum } from '/@/model/desktop/designer';
  import { useScript } from '/@/hooks/web/useScript';
  import useApiRequest from '/@/hooks/event/useApiRequest';
  const A_MAP_URL = 'https://webapi.amap.com/maps?v=2.0&key=4b3856cde2cd0421211ccc386669b33a';
  const { changeApiOptions } = useApiRequest();
  const props = withDefaults(
    defineProps<{
      type: DesktopComponent;
      w: number;
      h: number;
      title: string;
      config: MapConfig;
    }>(),
    {
      type: DesktopComponent.MAP,
      w: 0,
      h: 0,
      config: () => {
        return MapProperties;
      },
    },
  );
  const chartRef = ref<HTMLDivElement | null>(null);
  const AMap = ref<any>();
  const map = ref<any>();
  const conId = 'containerMap' + Math.ceil(Math.random() * 99999);
  import DingImg from '/@/assets/desktop/ding.png';
  const { toPromise } = useScript({ src: A_MAP_URL });
  onMounted(() => {
    initMap();
  });
  watch(
    () => props.config,
    () => {
      markerByLngLat();
    },
    {
      deep: true,
    },
  );
  async function initMap() {
    await toPromise();
    await nextTick();
    const wrapEl = unref(chartRef);

    if (!wrapEl) return;
    AMap.value = (window as any).AMap;
    map.value = new AMap.value.Map(conId, {
      zoom: 16,
      center: [116.316348, 39.992875],
      resizeEnable: true,
    });

    markerByLngLat();
  }
  async function markerByLngLat() {
    let config = props.config;
    if (config.apiConfig?.path) {
      let lnglat: any[] = [];
      let res = await changeApiOptions(config.apiConfig);
      if (res.list && Array.isArray(res.list)) {
        res.list.map((ele) => {
          lnglat.push({
            ...ele,
            key: config.primaryKey ? ele[config.primaryKey] : '',
            name: config.primaryName ? ele[config.primaryName] : '',
          });
        });
      }
      AMap.value.plugin(['AMap.Geolocation', 'AMap.Geocoder'], function () {
        map.value.getAllOverlays('marker').forEach((o) => {
          map.value.remove(o);
        });

        if (config?.panelConfig?.enabled) {
          if (config?.panelConfig?.clickShow) {
            var infoWindow = new AMap.value.InfoWindow();
            function markerClick(e) {
              infoWindow.setContent(e.target.content);
              infoWindow.open(map.value, e.target.getPosition());
            }
            for (var i = 0; i < lnglat.length; i++) {
              if (lnglat[i].key) {
                var poi = lnglat[i].key.split(',');
                var marker: any = [];
                var text: any = [];
                var name: any = [];
                if (config?.panelConfig?.enabled) {
                  //构建信息窗体中显示的内容
                  var info: Array<string> = [];
                  let panelConfigTitle = '';
                  if (config?.panelConfig?.titleType == PanelTitleTypeEnum.DEFAULT) {
                    if (config?.panelConfig?.title) {
                      panelConfigTitle = config.panelConfig.title;
                    }
                  } else {
                    if (config.panelConfig.titleField) {
                      panelConfigTitle = lnglat[i][config.panelConfig.titleField];
                    }
                  }

                  info.push(`<div class="map-title">${panelConfigTitle}</div>`);
                  if (
                    config.panelConfig &&
                    config.panelConfig?.config &&
                    config.panelConfig.config.length > 0
                  ) {
                    for (let index = 0; index < config.panelConfig.config.length; index++) {
                      const element = config.panelConfig.config[index];
                      let arrangeType = config.panelConfig.arrangeType;
                      if (element.hasFullRow) {
                        arrangeType = PanelArrangeTypeEnum.ONE;
                      }
                      let flexClass =
                        arrangeType == PanelArrangeTypeEnum.ONE
                          ? 'flex-100 map-item'
                          : 'flex-50 map-item';
                      let mapItemLabel = element.label ? element.label + ':' : '';
                      let boldClass = element.fontWeightBold ? 'map-item-bold' : '';
                      let alignClass = element.fontAlign;
                      let valueTitle = '';
                      if (element.value) valueTitle = lnglat[i][element.value];
                      info.push(
                        `
              <div class="${flexClass} ${alignClass}">
              <span  class="map-item-label ${boldClass} ">${mapItemLabel}</span>
              <span class="map-item-value ${boldClass} ">${valueTitle}</span>
              </div>
              `,
                      );
                    }
                  }
                  let panelConfigTitleStyle = `width: ${panelConfigTitle.length * 12 + 120}px;`;
                  let infoContent = `<div class='desktop-map-info-box' style="${panelConfigTitleStyle}">
                                  <div class="desktop-map-info-content">${info.join('')}</div>
                                <div class="desktop-map-item-fixed-top-btn"></div>

                                  </div>
                                    <div class="desktop-map-item-fixed-btn1"></div>
                                  <div class="desktop-map-item-fixed-btn2"></div>
                                  <div class="desktop-map-item-fixed-btn3"></div>
                                  `;
                  marker[i] = new AMap.value.Marker({
                    position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                    icon: DingImg,
                  });
                  marker[i].content = infoContent;
                  marker[i].on('click', markerClick);
                  marker[i].emit('click', { target: marker[i] });
                  map.value.add(marker[i]);
                }

                if (lnglat[i].name) {
                  let style = `width: ${lnglat[i].name.length * 12 + 10}px;`;
                  let infoNameContent = `<div style="${style}" class="primary-name">${lnglat[i].name}</div>`;
                  name[i] = new AMap.value.Marker({
                    position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                    content: infoNameContent, // 将 html 传给 content
                    offset: new AMap.value.Pixel(-8, 34),
                    anchor: 'center', // 设置文本标记锚点
                    cursor: 'context-menu',
                  });
                  map.value.add(name[i]);
                }
              }
            }
          } else {
            for (var i = 0; i < lnglat.length; i++) {
              if (lnglat[i].key) {
                var poi = lnglat[i].key.split(',');
                var marker: any = [];
                var text: any = [];
                var name: any = [];
                marker[i] = new AMap.value.Marker({
                  position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                  icon: DingImg,
                });

                // 将创建的点标记添加到已有的地图实例：
                map.value.add(marker[i]);
                if (config?.panelConfig?.enabled) {
                  //构建信息窗体中显示的内容
                  var info: Array<string> = [];
                  let panelConfigTitle = '';
                  if (config?.panelConfig?.titleType == PanelTitleTypeEnum.DEFAULT) {
                    if (config?.panelConfig?.title) {
                      panelConfigTitle = config.panelConfig.title;
                    }
                  } else {
                    if (config.panelConfig.titleField) {
                      panelConfigTitle = lnglat[i][config.panelConfig.titleField];
                    }
                  }

                  info.push(`<div class="map-title">${panelConfigTitle}</div>`);
                  if (
                    config.panelConfig &&
                    config.panelConfig?.config &&
                    config.panelConfig.config.length > 0
                  ) {
                    for (let index = 0; index < config.panelConfig.config.length; index++) {
                      const element = config.panelConfig.config[index];
                      let arrangeType = config.panelConfig.arrangeType;
                      if (element.hasFullRow) {
                        arrangeType = PanelArrangeTypeEnum.ONE;
                      }
                      let flexClass =
                        arrangeType == PanelArrangeTypeEnum.ONE
                          ? 'flex-100 map-item'
                          : 'flex-50 map-item';
                      let mapItemLabel = element.label ? element.label + ':' : '';
                      let boldClass = element.fontWeightBold ? 'map-item-bold' : '';
                      let alignClass = element.fontAlign;
                      let valueTitle = '';
                      if (element.value) valueTitle = lnglat[i][element.value];
                      info.push(
                        `
              <div class="${flexClass} ${alignClass}">
              <span  class="map-item-label ${boldClass} ">${mapItemLabel}</span>
              <span class="map-item-value ${boldClass} ">${valueTitle}</span>
              </div>
              `,
                      );
                    }
                  }
                  let panelConfigTitleStyle = `width: ${panelConfigTitle.length * 12 + 120}px;`;
                  let infoContent = `<div class='desktop-map-info-box' style="${panelConfigTitleStyle}">
            <div class="desktop-map-info-content">${info.join('')}</div>
           <div class="desktop-map-item-fixed-top-btn"></div>

            </div>
              <div class="desktop-map-item-fixed-btn1"></div>
            <div class="desktop-map-item-fixed-btn2"></div>
            <div class="desktop-map-item-fixed-btn3"></div>
            `;
                  text[i] = new AMap.value.Marker({
                    position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                    content: infoContent, // 将 html 传给 content
                    offset: new AMap.value.Pixel(40, 20),
                  });
                  map.value.add(text[i]);
                }

                if (lnglat[i].name) {
                  let style = `width: ${lnglat[i].name.length * 12 + 10}px;`;
                  let infoNameContent = `<div style="${style}" class="primary-name">${lnglat[i].name}</div>`;
                  name[i] = new AMap.value.Marker({
                    position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                    content: infoNameContent, // 将 html 传给 content
                    offset: new AMap.value.Pixel(-8, 34),
                    anchor: 'center', // 设置文本标记锚点
                    cursor: 'context-menu',
                  });
                  map.value.add(name[i]);
                }
              }
            }
          }
        } else {
          for (var i = 0; i < lnglat.length; i++) {
            if (lnglat[i].key) {
              var poi = lnglat[i].key.split(',');
              var marker: any = [];
              var text: any = [];
              var name: any = [];
              marker[i] = new AMap.value.Marker({
                position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                icon: DingImg,
              });

              // 将创建的点标记添加到已有的地图实例：
              map.value.add(marker[i]);

              if (lnglat[i].name) {
                let style = `width: ${lnglat[i].name.length * 12 + 10}px;`;
                let infoNameContent = `<div style="${style}" class="primary-name">${lnglat[i].name}</div>`;
                name[i] = new AMap.value.Marker({
                  position: poi, // 经纬度对象，也可以是经纬度构成的一维数组[116.39, 39.9]
                  content: infoNameContent, // 将 html 传给 content
                  offset: new AMap.value.Pixel(-8, 34),
                  anchor: 'center', // 设置文本标记锚点
                  cursor: 'context-menu',
                });
                map.value.add(name[i]);
              }
            }
          }
        }

        map.value.setFitView();
      });
    }
  }
</script>

<style lang="less" scoped>
  .box {
    .item-title {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 40px;
      line-height: 40px;
      color: #262626;
      font-size: 14px;
      padding-left: 16px;
    }

    .item-title::after {
      content: '';
      display: block;
      position: absolute;
      height: 1px;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: #f0f0f0;
    }

    .item {
      width: 100%;
      height: 100%;
    }
  }
</style>
<style>
  .desktop-map-info-box {
    position: relative;
    opacity: 0.8;
    background-image: linear-gradient(to right, #fff, #fcfcfc);
    margin-right: 15px;
    min-width: 240px;
  }

  .desktop-map-item-fixed-top-btn {
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 28px;
    background-size: 100%;
    background-repeat: no-repeat;
    background-image: url('/@/assets/desktop/ding1.png');
    z-index: 2;
  }

  .desktop-map-item-fixed-btn1 {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 15px;
    height: 15px;
    background-size: 100%;
    background-repeat: no-repeat;
    background-image: url('/@/assets/desktop/top.png');
    background-color: #fff;
    border-right: 1px solid #99bafd;
    z-index: 2;
  }

  .desktop-map-item-fixed-btn2 {
    position: absolute;
    top: 15px;
    right: 0;
    bottom: 15px;
    width: 15px;
    background-size: 100%;
    background-repeat: repeat;
    background-image: url('/@/assets/desktop/middle.png');
    z-index: 2;
  }

  .desktop-map-item-fixed-btn3 {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 15px;
    height: 15px;
    background-size: 100%;
    background-repeat: no-repeat;
    background-image: url('/@/assets/desktop/bottom.png');
    z-index: 2;
  }

  .desktop-map-info-content {
    /* background-color: #fff; */
    display: flex;
    flex-wrap: wrap;
    padding: 40px 30px 15px 15px;
    border: 1px solid #99bafd;
    border-right: none;
  }

  .desktop-map-info-box .flex-100 {
    flex-basis: 100%;
  }

  .desktop-map-info-box .flex-50 {
    flex-basis: 48%;
  }

  .desktop-map-info-box .map-item {
    display: flex;
    flex-wrap: nowrap;
    margin: 4px 0;
    overflow: hidden;
  }

  .desktop-map-info-box .map-title {
    position: absolute;
    top: 4px;
    left: 28px;
    flex-basis: 100%;
    font-size: 13px;
    color: #30353f;
    height: 24px;
    padding-left: 15px;
    display: flex;
    align-items: center;
    min-width: 120px;
    font-weight: 600;
    background-image: linear-gradient(to right, #99bafd, #fff);
  }

  .desktop-map-info-box .map-item-label {
    font-size: 12px;
    color: #30353f;
    margin-right: 12px;
    font-weight: 400;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .desktop-map-info-box .map-item-value {
    font-size: 12px;
    color: #30353f;
    font-weight: 400;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .desktop-map-info-box .map-item-bold {
    font-weight: 600;
  }

  .amap-icon img {
    width: 35px;
    height: 39px;
  }

  .desktop-map-info-box .left {
    justify-content: flex-start;
  }

  .desktop-map-info-box .center {
    justify-content: center;
  }

  .desktop-map-info-box .right {
    justify-content: flex-end;
  }

  .primary-name {
    border-width: 0;
    text-align: center;
    font-size: 12px;
    color: #fff;
    font-weight: bold;
    margin-top: 15px;
    background: rgb(59 130 246 / 70%);
  }

  .amap-info-content {
    padding: 0;
    box-shadow: none;
    background-color: transparent;
  }

  .amap-info-close {
    z-index: 2;
  }

  .amap-info-sharp {
    display: none;
  }

  .amap-info-contentContainer:hover .amap-info-outer,
  .amap-menu-outer:hover {
    box-shadow: none;
    background-color: transparent;
  }
</style>
