<template>
  <div class="mv-map-container" :class="'theme-' + theme">
    <div :id="id" class="mv-map"></div>
    <slot></slot>
  </div>
</template>

<script>
import { lazyAMapApiLoaderInstance, initMapSdk } from "../lib/init-map";
import { getThemeConfig, getThemeType } from "../lib/theme";
import { initBusinessSdk } from "../lib/sdk/business-sdk";
import config from "../lib/config/index.js";

let businessSdkObj = null;
const { DEFAULT_MAP_ID } = config;

export default {
  /**
   * @description     地图组件
   * @author          朱琦
   * @time            2022/3/3
   */
  name: "MvMap",
  props: {
    // 地图实例id
    id: {
      type: String,
      default: () => DEFAULT_MAP_ID
    },
    // 地图事件监听数组
    mapEventType: {
      default: () => [],
      type: Array
    },
    // 地图加载配置
    mapConfig: {
      type: Object,
      default: () => {
        return {};
      }
    },
    // 业务配置
    businessConfig: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      initMapConfig: null,
      theme: "",
      provinceLayer: null,

      // 向子孙组件传递数据
      mapConfigure: {
        mapLoadFinish: false, // 地图是否加载完成
        mapId: this.id,
        mapConfig: this.mapConfig,
        theme: this.mapConfig.theme || "dark",
        roadType: this.businessConfig.roadType,
        areaCode:
          this.businessConfig.areaConfig && this.businessConfig.areaConfig.code
      }
    };
  },
  provide() {
    return {
      mapConfigure: this.mapConfigure
    };
  },
  watch: {
    // 'businessConfig.roadType': {
    //   handler () {
    //     this.changeRoadType( this.businessConfig.roadType )
    //   },
    //   deep: true
    // }
  },
  beforeCreate() {},
  created() {},
  mounted() {
    this.createMvMap();
  },
  methods: {
    /**
     * 创建地图
     */
    createMvMap() {
      lazyAMapApiLoaderInstance.mapLoad().then((AMap) => {
        // 主题类型初始化
        this.theme = getThemeType(this.mapConfig.theme);

        // 地图配置初始化
        this.initMapConfig = Object.assign(
          {},
          getThemeConfig(this.theme).mapConfig,
          this.mapConfig,
          { theme: this.theme }
        );

        // 创建地图 map不能挂载到vue data上，vue3会报错
        const map = new AMap.Map(this.id, this.initMapConfig);

        // 初始化
        this.init(map);

        // 地图初始化事件触发
        this.$emit("map-load", map);
      });
    },
    /**
     * 初始化
     */
    async init(map) {
      this.mapConfigure.mapConfig = this.initMapConfig;
      this.mapConfigure.theme = this.theme;
      this.mapConfigure.areaCode =
        this.businessConfig.areaConfig && this.businessConfig.areaConfig.code;

      // 地图加载完成， 改变mapLoadFinish值 所有地图相关子孙组件进行初始化工作
      this.mapConfigure.mapLoadFinish = true;

      // 初始化地图sdk
      const params = {
        map: map,
        mapId: this.id,
        mapConfig: this.initMapConfig,
        businessConfig: this.businessConfig
      };
      const mapSdk = initMapSdk(params, this.pointClick);

      // 初始化业务sdk
      this.businessConfig.sdkConfig &&
        (businessSdkObj = initBusinessSdk(
          this.businessConfig.sdkConfig,
          mapSdk
        ));

      // 初始化地区
      if (this.businessConfig.areaConfig) {
        this.provinceLayer = await this.$mapSdk(this.id).createMvMapProvince(
          this.businessConfig.areaConfig
        );
      }

      // 注册地图监听事件
      if (this.mapEventType.length > 0) {
        this.mapEventType.forEach((type) => {
          map.on(type, this.mapEventFun);
        });
      }
    },
    /**
     * 修改主题
     */
    setTheme(theme) {
      this.theme = theme;
      this.mapConfigure.theme = theme;
      const mapStyle = getThemeConfig(theme).mapConfig.mapStyle;
      this.$mapSdk(this.id).setTheme(theme, mapStyle);
    },

    /**
     * 根据业务名获取业务sdk
     * @param {String} sdkName 业务名称
     * @returns 业务类方法
     */
    getBusinessSdk(sdkName) {
      return businessSdkObj[sdkName];
    },
    /**
     * 主题切换
     * @param {String} theme 主题类型
     */
    changeTheme(theme) {
      this.theme !== theme && this.setTheme(theme);
    },
    /**
     * 路网类型改变
     * params.roadType 路网类型
     */
    changeRoadType(roadType) {
      this.mapConfigure.roadType !== roadType &&
        (this.mapConfigure.roadType = roadType);
    },
    /**
     * 地图事件触发
     */
    mapEventFun(e) {
      this.$emit("map-load-event", e);
    },
    /**
     * 地图中 被选中点标记 点击回调
     */
    pointClick(e, data, config) {
      this.$emit("point-click", e, data, config);
    },
    /**
     * 销毁相关事件
     */
    destroy() {
      if (!this.$mapSdk(this.id)) return;
      const map = this.$mapSdk(this.id).getMvMap();
      // 清除地图实例上的所有mapEventType事件绑定
      if (this.mapEventType.length > 0) {
        this.mapEventType.forEach((type) => {
          map.off(type, this.mapEventFun);
        });
      }
      // 销毁地图，并清空地图容器
      map && map.destroy();
    }
  },
  beforeDestroy() {
    this.destroy();
  },
  beforeUnmount() {
    this.destroy();
  }
};
</script>

<style scoped>
.mv-map-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.mv-map {
  width: 100%;
  height: 100%;
  position: absolute;
}

.mv-map /deep/ .amap-logo {
  display: none !important;
  visibility: hidden !important;
}
</style>
<style>
/* 点 悬浮框样式 */

/* marker label */
.amap-marker-label:after,
.amap-marker-label:before {
  content: "";
  display: block;
  position: absolute;
  margin: auto;
  width: 0;
  height: 0;
  border: solid transparent;
  border-width: 5px;
  left: 0;
  right: 0;
}
.amap-marker-label:before {
  bottom: -10px;
  border-top-color: #6faefa;
}
.amap-marker-label:after {
  bottom: -9px;
  border-top-color: #fff;
}
/* dark */
.mv-map-container.theme-dark .mv-map-ui-hover-title.overlay-title,
.mv-map-container.theme-dark .amap-marker-label {
  background-color: rgba(2, 6, 15, 0.8);
  color: #00baff;
  border: 1px solid #0078ff;
}
.mv-map-container.theme-dark .mv-map-ui-hover-title.overlay-title:after,
.mv-map-container.theme-dark .amap-marker-label:after {
  border-top-color: #041327 !important;
}
.mv-map-container.theme-dark .mv-map-ui-hover-title.overlay-title:before,
.mv-map-container.theme-dark .amap-marker-label:before {
  border-top-color: #0078ff !important;
}
/* light */
.mv-map-container.theme-light .mv-map-ui-hover-title.overlay-title,
.mv-map-container.theme-light .amap-marker-label {
  background-color: #fff;
  color: #6faefa;
  border: 1px solid #6faefa;
}
.mv-map-container.theme-light .mv-map-ui-hover-title.overlay-title:after {
  border-top-color: #fff !important;
}
.mv-map-container.theme-light .mv-map-ui-hover-title.overlay-title:before {
  border-top-color: #6faefa !important;
}

/* map ui hover */
.amap-container .overlay-canvas {
  cursor: pointer;
}
</style>
