import React, {Component} from 'react';
import { observable, action, computed } from 'mobx';
import isEmpty from 'lodash/isEmpty';
import has from 'lodash/has';

export default class MapUtil{
    mapRef;

    constructor(ref){
        this.mapRef = ref;
    }

    amap;
    markers = [];//google map's marker collection
    circles = [];//google map's circle collection
    polyline;//google map's polyline
    infoWindow;

    setRef = ref => ref && (this.mapRef = ref);

    //#region 地图初始化状态
    @observable _mapInited = false;
    @computed get mapInited(){return this._mapInited}
    set mapInited(v){this._mapInited = v}
    //#endregion

    //#region 设置地图实例
    get mapInstance(){
        if(this.isAmap){
            return this.amap;
        }
        else if(this.isGoogleMap){
            return this.mapRef.getMap('google');
        }
    }

    set mapInstance(v){
        this.amap = v;
    }
    //#endregion

    //#region 地图属性
    //获取地图配置信息
    get defaultMapParams(){
        return this.mapRef.getDefaultMapParams();
    }

    //当前地图类型
    get currentMapType(){
        return this.mapRef.getMapType();
    }

    //是否是高德地图
    get isAmap(){
        return this.currentMapType.toLowerCase() === 'gaode';
    }

    //是否是google地图
    get isGoogleMap(){
        return this.currentMapType.toLowerCase() === 'google';
    }

    //高德地图webservice key
    get amapWebServiceKey(){
        try{
            return this.defaultMapParams.gaodeMapWebServiceKey;
        }catch(e){
            return '';
        }
    }

    //google地图key
    get googleMapKey(){
        try{
            return this.defaultMapParams.googleMapKey;
        }catch(e){
            return '';
        }
    }
    //#endregion

    //#region 地图操作
    //设置地图类型
    setMapType = type => !isEmpty(type) && this.mapRef.setMapType(type);
    //#endregion

    //创建marker icon
    createIcon = image => {
        if(this.isAmap){
            return new window.AMap.Icon({
                image,
                // 图标尺寸
                size: new window.AMap.Size(36, 36),
                // 图标所用图片大小
                imageSize: new window.AMap.Size(36, 36),
            })
        }else if(this.isGoogleMap){
            return {
                url: image,
                scaledSize: new window.google.maps.Size(32, 32),
            }
        }
    }

    //清除marker
    clearMarker = id => {
        if(this.isAmap){
            let overlays = this.mapInstance.getAllOverlays("marker");
            if(id){
                overlays.map(overlay => {
                    const extData = overlay.getExtData();
                    if(has(extData, "id") && (extData.id == id)){
                        this.mapInstance.remove(overlay);
                    }
                });
            }else{
                overlays.map(overlay => {
                    this.mapInstance.remove(overlay);
                });
            }
        }else if(this.isGoogleMap){
            console && console.debug(this.markers);
            // if(markerGoogle){
            //     markerGoogle.setMap(null);
            // }
        }
    }

    //添加marker
    addMarker = (data, icon, offset, otherParams = {}) => {
        const markerProps = {};
        const {latitude, longitude, id} = data;
        const {events} = otherParams;
        let marker;
        if(this.isAmap){
            Object.assign(markerProps, {position: new window.AMap.LngLat(longitude, latitude)});
            id && Object.assign(markerProps, {extData: {id}});
            icon && Object.assign(markerProps, {icon});
            offset && Object.assign(markerProps, {offset});
            Object.assign(markerProps, otherParams);
            marker = new window.AMap.Marker(markerProps);
            this.mapInstance.add(marker);
            events && events.length > 0 && events.map(e => {
                window.AMap.event.addListener(marker, e.event, e.onEventHandle);
            })
        }else if(this.isGoogleMap){
            Object.assign(markerProps, {position: {lng:Number(longitude), lat:Number(latitude)}});
            id && Object.assign(markerProps, {extData: {id}});
            icon && Object.assign(markerProps, {icon});
            Object.assign(markerProps, otherParams);
            marker = this.mapRef.getGoogleMapFuncs().newMarker(markerProps);
            events && events.length > 0 && events.map(e => {
                window.AMap.event.addListener(marker, e.event, e.onEventHandle);
            })
            this.markers.push(marker);
        }
        return marker;
    }

    //清除circle
    clearCircle = id => {
        if(this.isAmap){
            let overlays = this.mapInstance.getAllOverlays("circle");
            if(id){
                overlays.map(overlay => {
                    const extData = overlay.getExtData();
                    if(has(extData, "id") && (extData.id == id)){
                        this.mapInstance.remove(overlay);
                    }
                });
            }else{
                overlays.map(overlay => {
                    this.mapInstance.remove(overlay);
                });
            }
        }else if(this.isGoogleMap){
            console && console.debug(this.circles);
            // if(markerGoogle){
            //     markerGoogle.setMap(null);
            // }
        }
    }

    //添加circle
    addCircle = (data, otherParams = {}) => {
        const circleProps = {};
        const {latitude, longitude, radius, id} = data;
        let circle;
        if(this.isAmap){
            Object.assign(circleProps, {
                center: new window.AMap.LngLat(longitude, latitude), // 圆心位置
                radius:  radius || 100,//半径
                strokeColor: otherParams.strokeColor || "#55B1F9", //线颜色
                strokeOpacity: otherParams.strokeOpacity || 1, //线透明度
                strokeWeight: otherParams.strokeWeight || 2, //线粗细度
                fillColor: otherParams.fillColor || "#55b1f9", //填充颜色
                fillOpacity: otherParams.fillOpacity || 0.2, //填充透明度,
                ...otherParams
            });
            id && Object.assign(circleProps, {extData: {id}});
            circle = new window.AMap.Circle(circleProps);
            this.mapInstance.add(circle);
        }else if(this.isGoogleMap){
            Object.assign(circleProps, {
                center: {lng:Number(longitude), lat:Number(latitude)}, // 圆心位置
                radius: radius || 500,//locationcheckscope, //半径
                strokeColor: otherParams.strokeColor || "#55B1F9", //线颜色
                strokeOpacity: otherParams.strokeOpacity || 1, //线透明度
                strokeWeight: otherParams.strokeWeight || 2, //线粗细度
                fillColor: otherParams.fillColor || "#55b1f9", //填充颜色
                fillOpacity: otherParams.fillOpacity || 0.2, //填充透明度,
                ...otherParams
            });
            id && Object.assign(circleProps, {extData: {id}});
            circle = this.mapRef.getGoogleMapFuncs().newCircle(circleProps)
            this.circles.push(circle);
        }
        return circle;
    }

    //清除polyline
    clearPolyline = () => {
        
    }

    //添加polyline
    addPolyline = (path, otherParams = {}) => {
        let polyline;
        if(this.isAmap){
            polyline = new window.AMap.Polyline({
                path,
                strokeColor: otherParams.strokeColor || '#55B1F9',
                ...otherParams
            });
            this.mapInstance.add(polyline);
        }else if(this.isGoogleMap){
            polyline = this.mapRef.getGoogleMapFuncs().newPolyline({
                path,
                geodesic: otherParams.strokeColor || true,
                strokeColor: otherParams.strokeColor || '#FF0000',
                strokeOpacity: otherParams.strokeColor || 1.0,
                strokeWeight: otherParams.strokeColor || 2,
                ...otherParams
            })
            this.mapRef.getGoogleMapFuncs().showCover(polyline);
        }
        return polyline;
    }

    //打开InfoWindow
    openInfoWindow = (data, otherParams) => {
        if(this.isAmap){
            const {marker, isCustom, content} = data;
            const infoWindow = new window.AMap.InfoWindow({
                isCustom,
                content,
                ...otherParams
            });
            infoWindow.open(this.mapInstance, marker.getPosition());
        }else if(this.isGoogleMap){
            this.infoWindow && this.infoWindow.close();
            const {content} = data;
            this.infoWindow = new google.maps.InfoWindow({
                content,
                ...otherParams
            });
            this.infoWindow.open(this.mapInstance);
        }
    }

    //关闭InfoWindow
    closeInfoWindow = () => {
        if(this.isAmap){
            this.mapInstance.clearInfoWindow();
        }else if(this.isGoogleMap){
            this.infoWindow && this.infoWindow.close();
        }
    }

    //清除地图所有数据
    clearMapData = () => {
        if(this.isAmap){
            this.mapInstance.clearMap();
        }else if(this.isGoogleMap){
            this.markers.map(m => this.mapRef.getGoogleMapFuncs().clearCover(m));
            this.polyline && this.mapRef.getGoogleMapFuncs().clearCover(this.polyline);
            this.infoWindow && this.infoWindow.close();
            this.markers.length = 0;
            this.polyline = null;
            this.infoWindow = null;
        }
    }

    //设置地图中心
    setCenter = data => {
        let position;
        if(this.isAmap){
            position = new window.AMap.LngLat(
                data.longitude,
                data.latitude
            )
            this.mapInstance.setCenter(position);
        }else if(this.isGoogleMap){
            position = {
                lng:Number(data.longitude),
                lat:Number(data.latitude)
            }
            this.mapRef.getGoogleMapFuncs().setCenter(position);
        }
    }

    //fit view
    setFitView = datas => {
        setTimeout(() => {
            if(this.isAmap){
                this.mapInstance.setFitView(datas, null, null, 18);
            }else if(this.isGoogleMap){
                const dataLen = datas.length;
                if(dataLen > 1){
                    let bounds = new window.google.maps.LatLngBounds();
                    datas.map(d => {
                        bounds.extend(new window.google.maps.LatLng(Number(d.latitude), Number(d.longitude)));
                    })
                    this.mapRef.getGoogleMapFuncs().fitBounds(bounds);
                }else{
                    this.mapRef.getGoogleMapFuncs().setCenter({lat:Number(datas[0].latitude), lng:Number(datas[0].longitude)});
                }
            }
        }, 50);
    }
    //#endregion
}