<template>
    <view class="container-box">
        <view :id="mapId" class="container"></view>

        <!-- info window弹框窗体 -->
        <component :is="componentView" ref="componentViewRef" />

        <slot></slot>
    </view>
</template>
<script>
import Vue from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader';
import { createPulseLinkLayer, createMarkerCluster, createMoveAlong, createMarker, createPolylineShow } from "./controller/createApi";
import { uniqueId,isEmpty } from 'lodash'
import {getMaxMinBounds,listCrudChange} from '@/utils/gdtq.js'

/**地图展示相关组件*/
import vehicleInfo from './components/vehicleInfo.vue';//聚合车辆弹框
import pastRoute from './components/pastRoute.vue'; //轨迹弹框

//组件映射
const componentsMapDefault = {
    markerCluster: vehicleInfo,
    moveAnimation: pastRoute,
}


export default {
	components: {
	},
	props: {
		//外部重置默认弹窗组件
		componentsMapProps: {
		    type: Object,
		    default: () => {}
		},
		mapConfig: {
		    type: Object,
		    default: () => { }
		},
		pointsData: {
		    type: Array,
		    default: () => []
		},
		pointsDataConfig: {
		    type: Object,
		    default: () => { }
		},
		toolMapKey: { //markerCluster moveAnimation(轨迹回放)  
		    type: String,
		    default: 'markerCluster'
		},
		isCreateInfoWindow: {
		    type: Boolean,
		    default: true
		},
		infoWindowConfig: {
		    type: Object,
		    default: () => {
		        return {
		            isCustom: true
		        }
		    }
		},
		//城市定位
		enableCityPositon: {
			type: Boolean,
			default: true
		}
	},
	watch: {
		pointsData: function(pointsData, prevPointsData)  {
			/**对比改变后的数据做业务处理*/
			// console.log('watch地图数据', pointsData, prevPointsData)
			if (this.map === null) return;
			this.createProjects(this.toolMapKey, { points: this.pointsData, prePoints: prevPointsData })
		}
	},
	
	data() {
		return {
			map: null,
			mapId:  uniqueId('gaode_map_'),
			
			/* 聚合相关 */
			cluster: undefined, //点聚合实例
			
			/* 轨迹相关 */
			 createMoveAlongFn: null,//轨迹回放响应式实例对象
			 allmarkerPro: undefined,
			 isMoveAlongWindow: undefined,
			 
			 /* 弹窗相关*/
			  createInfoWindow: undefined,
			  componentView: undefined,
			  
			  satelliteLayer: '', //卫星图
	
			trafficLayer: '', //实时路况
			
			isMoveAlongWindow: false,
		}
	},
	
	
	mounted() {
		let that = this;
		//组件映射
		this.componentsMap = Object.assign(componentsMapDefault,this.componentsMapProps)
		
		/* 窗体相关 */
		this.createInfoWindow = function createInfoWindowFn() {
			let infoWindow;
			let cluster2;
		
			function add(data) {
				let { cluster, clusterData, lnglat, offset, componentsMapKey } = data
				if (clusterData) {
					cluster2 = clusterData.length > 0 ? clusterData : [cluster.p]
				}
		
				that.componentView = that.componentsMap[componentsMapKey]
				
				that.$nextTick(() => {
					console.log(that.$refs.componentViewRef,'that.that.$refs.componentViewRef')
					that.$refs.componentViewRef.callBack(data, closeWindow)
					
					if (clusterData?.length > 1) return;
					infoWindow = new AMap.InfoWindow({
						...that.infoWindowConfig,
						content: that.$refs.componentViewRef.$el,
						offset: offset
					});
					that.map.on('click', function () {
						infoWindow.close();
					});
					setTimeout(() => {
						infoWindow.open(that.map, [lnglat.lng, lnglat.lat]);
						infoWindow.setOffset(new AMap.Pixel(0, -23));
					}, 0);
				})
				
			}
		
			function setPosition(data) {
				infoWindow.setPosition(data);
			}
		
			function closeWindow() {
				if (infoWindow) {
					infoWindow.close();
				}
			}
		
			function getItem() {
				return cluster2
			}
			
			function getinfoWindow() {
				return infoWindow
			}
			
			return {
				add: add,
				setPosition: setPosition,
				closeWindow: closeWindow,
				getItem: getItem,
				getinfoWindow: getinfoWindow,
			};
		}()
		
		
		this.initMap()

	},
	
	methods: {
		
		initMap() {
		    AMapLoader.load({
		        key: "08d130e013f96dcf4329cf7bac274c8e",  // 申请好的Web端开发者Key，首次调用 load 时必填
		        version: "2.0",      // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
		        plugins: [
		            'AMap.MarkerCluster', 'AMap.Polyline', 'AMap.MoveAnimation', 'AMap.CircleEditor',
		            'AMap.Driving', 'AMap.AutoComplete', 'AMap.Scale','AMap.MouseTool', 'AMap.Geolocation','AMap.CitySearch',
		        ],       // 需要使用的的插件列表，如比例尺'AMap.Scale'等
		        Loca: {                // 是否加载 Loca， 缺省不加载
		            "version": '2.0.0'  // Loca 版本，缺省 1.3.2
		        },
		    }).then((AMap) => {
				console.log('AMap Load','data')
		        this.map = new AMap.Map(this.mapId, {  //设置地图容器id
		            viewMode: "3D",    //是否为3D地图模式
		            zoom: 3,           //初始化地图级别
		            center: [105.602725, 37.076636], //初始化地图中心点位置
		            ...this.mapConfig
		        });
		        this.createProjects(this.toolMapKey, { points: this.pointsData, pointsDataConfig: this.pointsDataConfig })
		
		        this.map.addControl(new AMap.Scale());
				
				if(this.enableCityPositon) {
					this.citySearch()
				}
		        
		
		        this.$emit('onload', this.map)
		    }).catch(e => {
		        console.log(e);
		    })
		},
		createProjects(key, data, callBack) {
		    if (!key) return
		    const toolMapFn = {
		        pulseLinkLayer: () => {//飞线
		            createPulseLinkLayer(this.map, data, callBack);
		        },
		        markerCluster: () => {//创建聚合点

		            if (!this.cluster) {
		                this.cluster = createMarkerCluster(this.map, data, (e) => {
		                    const { clusterData, lnglat } = e
		                    if (clusterData.length > 1) {
		                      
		                        let {southWest,northEast} = getMaxMinBounds(clusterData.map((e) => [e.item.lng,e.item.lat]))
		                        let bounds = new AMap.Bounds(southWest, northEast)
		                       
		                        this.map.setBounds(bounds,true,[80, 80, 40, 40])
		                    }
							
		                    // console.log(e, 'eeeee')
							if (clusterData?.length > 1) return;
							this.$emit('handleMarkerClick',e)
		                    // this.createInfoWindow.closeWindow()
		                    // this.createInfoWindow.add({ ...e, offset: [0, -14], componentsMapKey: 'markerCluster' })//创建窗体
		                });
		            } else {
		                let { points, prePoints } = data
		                this.cluster.setData(points)
		
		                /*移动窗体 */
		                /* let activeItem = this.createInfoWindow.getItem()
		       
		                if (activeItem) {
		
		                    let filterItem = points.filter((item) => {
		                        return item.item.id == activeItem[0].item.id
		                    })
		                    if (!isEmpty(filterItem)) {
		                        this.createInfoWindow.setPosition([filterItem[0].item.lng, filterItem[0].item.lat])
		                    } else {
		                        this.createInfoWindow.closeWindow()
		                    }
		
		                } */
						
						
						let newPoint = points.map(e => e.item)
						let oldPoint = prePoints.map(e => e.item)
						let {adds,deletes} = listCrudChange(newPoint,oldPoint)
						
						console.log(adds,'addsaddsadds')
						if( adds.length>=2) {
							let {southWest,northEast} = getMaxMinBounds(adds.map((e) => [e.lng,e.lat]))
							let bounds = new AMap.Bounds(southWest, northEast)
							this.$nextTick(() => {
								this.map.setBounds(bounds,true,[80, 80,40, 40])
							})
							
							console.log(bounds,'boundsbounds',this.map)
						} else if (adds.length == 1) {
							let item = adds[0]
							this.map.setZoomAndCenter(18, [item.lng,item.lat], true);
						}
					
		
		            }
		
		        },
		        moveAnimation: () => {//创建轨迹回放
		            let index = 0;
		            if (this.createInfoWindow.getinfoWindow()) {
		                this.createInfoWindow.closeWindow();
		            }
		            this.createMoveAlongFn = createMoveAlong(this.map, data, (key, e) => {
		                if (key === 'moving') {
		                    index = e.index
		                    this.$emit('moving', e)
		                    /* if (this.createInfoWindow.getinfoWindow()) {
		                        if (this.isMoveAlongWindow) {
		                            this.createInfoWindow.setPosition([e.target.getPosition().lng, e.target.getPosition().lat])
		                            if (this.$refs.componentViewRef) {
		                                this.$refs.componentViewRef.callBack(e, this.createInfoWindow.closeWindow)
		                            }
		                        }
		
		                    } */
							this.$emit('handleMarkerClick',e, key)
		                }
		                if (key === 'moveTo') {
		                   /* if (this.createInfoWindow.getinfoWindow()) {
		                        if (this.isMoveAlongWindow) {
		                            this.createInfoWindow.setPosition(e.lnglat)
		                            if (this.$refs.componentViewRef) {
		                                this.$refs.componentViewRef.callBack(e, this.createInfoWindow.closeWindow)
		                            }
		                        }
		                    } */
							this.$emit('handleMarkerClick',e, key)
		                }
		                if (key === 'click') {
                            if(e.resetIdx>index){
                                e.index = e.resetIdx
                            }else{
                                e.index = index
                            }
							
							this.$emit('handleMarkerClick',e, key)
		                   /* this.isMoveAlongWindow = true
		                    if (!this.isCreateInfoWindow) return;
		                    this.createInfoWindow.add({ index, lnglat: e.target.getPosition(), offset: [0, -23], componentsMapKey: 'moveAnimation' })//创建窗体 */
		                }
		            })
		        },
		        createMarker: () => { //创建标注点
		            this.allmarkerPro = createMarker(this.map, data, (key, e) => { //返回目前地图上所有Mark实例
		                if (this.createInfoWindow.getinfoWindow()) {
		                    this.createInfoWindow.closeWindow();
		                }
		                console.log('创建标注点', e)
		                let lng = Number(e.lng02)
		                let lat = Number(e.lat02)
		                this.isMoveAlongWindow = false
		
		                if (e.hiddenInfoWindow) return
		                this.createInfoWindow.add({ lnglat: { lng, lat }, offset: [0, 0], componentsMapKey: e.type, info: e })//创建窗体
		            })
		        },
		        removeAllMarkers: () => {//删除所有创建的标注点
		            if (this.allmarkerPro) {
		                this.allmarkerPro.removeAllMarkers()
		            }
		        },
		        createPolyline: () => {//创建展示路线
		            createPolylineShow(this.map, data)
		        }
		    }
		    toolMapFn[key]();
		},
		citySearch() {
		    //实例化城市查询类
			let that = this;
		    var citysearch = new AMap.CitySearch();
		
		    //自动获取用户IP，返回当前城市
		    citysearch.getLocalCity(function(status, result) {
		        if (status === 'complete' && result.info === 'OK') {
		            if (result && result.city && result.bounds) {
		                var citybounds = result.bounds;
		                //地图显示当前城市
		                that.map.setBounds(citybounds,true);
		            }
		        } else {
		            
		        }
		    });
		},
		setisMoveAlongWindow(e) {
		    isMoveAlongWindow = e
		},
		
		/**创建路线 */
		createPolyline(data, option) {
		
		    let polyline
		    polyline = new AMap.Polyline({
		        map: this.map,
		        path: data,
		        showDir: true,
		        strokeStyle: "solid",
		        strokeColor: "#027AFF",  //线颜色
		        strokeWeight: 6,      //线宽
		        strokeOpacity: 1,
		        ...option,
		    });
		
		    return polyline
		},
		/**移除覆盖物 */
		removeOverlays(Overlays) {
		    this.map.remove(Overlays)
		},
		/**创建围栏 */
		createPolygon(data, option) {
		
		    let Polygon
		    Polygon = new AMap.Polygon({
		        map: this.map,
		        path: data,
		        strokeStyle: "solid",
		        fillColor: '#00b0ff',
		        strokeColor: '#80d8ff',
		        strokeWeight: 2,     //轮廓线宽度
		        ...option,
		    });
		
		    return Polygon
		},
		
		/**创建圆 */
		createCircle(center, option) {
		
		    let Circle
		    Circle = new AMap.Circle({
		        center: center,
		        radius: 50, //半径
		        borderWeight: 3,
		        strokeColor: "#FF33FF",
		        strokeOpacity: 1,
		        strokeWeight: 6,
		        strokeOpacity: 0.2,
		        fillOpacity: 0.4,
		        fillColor: '#1791fc',
		        ...option,
		    });
		    this.map.add(Circle)
		
		    return Circle
		},
		/**批量创建标记点 */
		batchCreateMarkers(data, option) {
		
		    let Markers = []
		    data.forEach(item => {
		        Markers.push(
		            new AMap.Marker({
		                position: item.position,
		                content: item.content,
		                offset: item.offset,
		                title: item.title,
		                ...option
		            })
		        )
		    });
		
		    this.map.add(Markers)
		
		    return Markers
		},
	
		// 坐标集合适配
		setBoundsPolygon(bounds,immediately){
		    let polygon = new AMap.Polygon({
		        path: bounds,
		    });
		    let mybounds = polygon.getBounds();
		    this.map.setBounds(mybounds,immediately);
		},
		/**视觉适配 */
		setFitView(...args) {
		    this.map.setFitView(...args);
		},
		
		/**设置中心点 */
		setCenter(...args) {
		    this.map.setCenter(...args);
		},
		/**地图缩放至指定级别并以指定点为地图显示中心点 */
		setZoomAndCenter(...args) {
		    this.map.setZoomAndCenter(...args);
		},
		
		/* 设置卫星图 */
		setStelliteLayer(isShow = true) {
			if (isShow) {
				if (!this.satelliteLayer) {
					this.satelliteLayer = new AMap.TileLayer.Satellite();
					this.satelliteLayer.setMap(this.map);
				} else {
					this.satelliteLayer.show();
				}
			} else {
				 if (this.satelliteLayer) this.satelliteLayer.hide();
			}
			
		},
		
	}
}


</script>
<style scoped lang="scss">
// 地图
::v-deep {
	.amap-logo {
		display: none !important;
	}
	.amap-copyright {
		 display: none !important;
	}
}


.container-box {
    width: 100%;
    height: 100%;
    position: relative;

    .showspeed-box {
        border-radius: 6px;
        overflow: hidden;
        position: absolute;
        right: 12px;
        top: 11px;
        height: 33px;
        color: #fff;
        display: flex;
        align-items: center;
        text-align: center;
        height: 33px;
        line-height: 33px;
        font-size: 12px;

        .flex-al {
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .checkbox {
            width: 84px;
            background: linear-gradient(180deg, #3296FF 0%, #027AFF 100%);
            border-radius: 6px 0px 0px 6px;

            :deep(.el-checkbox__label) {
                color: #fff;
            }

            :deep(.el-checkbox) {
                height: 33px;
                line-height: 33px;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        }

        .speed-60 {
            width: 30px;
            background: #16B92A;
        }

        .speed-80 {
            width: 45px;
            background: #0000FE;
        }

        .speed-100 {
            width: 53px;
            background: #F98202;

        }

        .speed-m100 {
            width: 71px;
            background: #FE0100;
            border-radius: 0px 6px 6px 0px;
        }
    }

    .mapToolBox {
        position: absolute;
        display: flex;
        max-width: 500px;
        overflow: auto;
        top: 10px;
        left: 30px;

    }
}

.container {
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 100%;
}
</style>