import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useEffect, useImperativeHandle, useRef, useState, } from 'react';
import { compact, isArray, isEmpty } from 'lodash';
import { renderToString } from 'react-dom/server';
import { useReactive } from 'ahooks';
import { getStorage } from '@component/utils';
import { GDMap } from '../map';
import { HeatMapLayer } from '../layer';
import cluster_blue from './cluster_blue.png';
import marker_blue from './marker_blue.png';
import set_cluster from './cluster';
import style from './style.module.css';
export const MapMarker = forwardRef((props, ref) => {
    const { data = [], icon = marker_blue, clusterIcon = cluster_blue, options = {}, onMarker, onCluster, district = false, isHeatMap = false, isMapStyle = false, isZoomMap = false, circle = false, distance = 1000, polygonOptions = {}, adcode = null, isCluster = true, loadedCallBack, } = props;
    const position = !isEmpty(compact(getStorage('position') ? getStorage('position').split(',') : []))
        ? compact(getStorage('position').split(','))
        : [116.398784, 39.910231];
    const mapOptions = Object.assign({ center: position, zoom: 6 }, options);
    const infoWindowRef = useRef(null);
    const markersEle = useRef([]);
    const districtEle = useRef(null);
    const polygons = useRef([]);
    const mapEle = useRef(null);
    const circleRef = useRef(null);
    const [styleStatus, setStyleStatus] = useState((options === null || options === void 0 ? void 0 : options.mapStyle) === 'amap://styles/darkblue');
    const showHeatMap = useReactive({
        show: false,
    });
    const clearMap = () => {
        mapEle.current.clearMap();
    };
    /**
     * marker点击事件
     * @param event
     */
    const onMarkerClick = (event) => {
        const marker = event.target;
        const position = marker.getPosition();
        const extData = marker.getExtData();
        if (mapEle.current && onMarker) {
            onMarker(extData);
            return;
        }
        setInfoWindow({
            position,
            extData,
        });
    };
    function setInfoWindow({ position, extData }) {
        var _a, _b, _c;
        if (infoWindowRef.current.getIsOpen()) {
            (_a = infoWindowRef.current) === null || _a === void 0 ? void 0 : _a.close();
        }
        (_b = infoWindowRef.current) === null || _b === void 0 ? void 0 : _b.setContent(renderInfoContent(extData));
        (_c = infoWindowRef.current) === null || _c === void 0 ? void 0 : _c.open(mapEle.current, position);
        mapEle.current.setCenter(position);
    }
    const createMaker = (item) => {
        const marker = new AMap.Marker({
            position: [item.lng, item.lat],
            icon: item.icon,
            clickable: true,
            extData: item,
            map: !isCluster && mapEle.current,
        });
        marker.on('click', onMarkerClick);
        return marker;
    };
    const getMarkers = (data) => {
        if (!infoWindowRef.current) {
            infoWindowRef.current = new AMap.InfoWindow({
                offset: new AMap.Pixel(10, -15),
                autoMove: true,
            });
        }
        return data.map((item) => createMaker(Object.assign({ icon: icon }, item)));
    };
    const setClusterEvent = () => {
        return [
            {
                type: 'click',
                eventHandle: (context, currentClusterObj) => {
                    let map = context.getMap();
                    if (map.getZoom() >= 15) {
                        let markers = currentClusterObj.markers, filterMarkers = [];
                        for (let i = markers.length - 1; i >= 0; i--) {
                            filterMarkers.unshift(markers[i].getExtData());
                        }
                        if (onCluster) {
                            onCluster(filterMarkers, (data) => {
                                setInfoWindow({
                                    position: currentClusterObj.lnglat,
                                    extData: data,
                                });
                            });
                            return;
                        }
                        setInfoWindow({
                            position: currentClusterObj.lnglat,
                            extData: filterMarkers,
                        });
                    }
                },
            },
        ];
    };
    const setMarkers = (data) => {
        markersEle.current = getMarkers(data);
        if (isCluster) {
            try {
                set_cluster(mapEle.current, markersEle.current, setClusterEvent(), clusterIcon, district, circle);
            }
            catch (e) {
                console.log('e', e);
            }
        }
    };
    // 缩放地图
    const setMapView = (type) => {
        if (!mapEle.current) {
            return;
        }
        let zoom = mapEle.current.getZoom();
        if (type === 'add') {
            zoom++;
            zoom = zoom >= 18 ? 18 : zoom;
        }
        else {
            zoom--;
            zoom = zoom <= 1 ? 1 : zoom;
        }
        mapEle.current.setZoom(zoom);
    };
    //热力图切换
    const toggleHeatMap = () => {
        var _a, _b;
        if (!mapEle.current) {
            return;
        }
        showHeatMap.show = !showHeatMap.show;
        (_a = mapEle.current) === null || _a === void 0 ? void 0 : _a.clearInfoWindow();
        (_b = mapEle.current) === null || _b === void 0 ? void 0 : _b.cluster.clearMarkers();
        if (!showHeatMap.show) {
            setMarkers(data);
        }
    };
    const setStyle = () => {
        if (!mapEle.current) {
            return;
        }
        const status = !styleStatus;
        mapEle.current.setMapStyle('amap://styles/' + (status ? 'darkblue' : 'fresh'));
        setStyleStatus(status);
    };
    /**
     * Infowin窗口渲染内容
     * @returns {string}
     */
    const renderInfoContent = (data) => {
        const { renderInfoContent } = props;
        const d = isArray(data) ? data : [data];
        if (renderInfoContent) {
            return renderInfoContent(d);
        }
        return renderToString(_jsx("ul", Object.assign({ className: style['popup_list'] }, { children: d.map((item, key) => {
                return (_jsx("li", Object.assign({ title: item === null || item === void 0 ? void 0 : item.name }, { children: (item === null || item === void 0 ? void 0 : item.url) ? (_jsx("a", Object.assign({ target: "_blank", href: item === null || item === void 0 ? void 0 : item.url }, { children: item === null || item === void 0 ? void 0 : item.name }))) : (item === null || item === void 0 ? void 0 : item.name) }), key));
            }) })));
    };
    /**
     * 地图加载完成后的回调
     * @param map
     */
    const onMapLoaded = (map) => {
        init(map, data);
    };
    const init = (map, data) => {
        mapEle.current = map;
        if (district) {
            drawBounds({
                map,
                district: districtEle.current,
                polygons: polygons.current,
                adcode: adcode || getStorage('code'),
                polygonOptions: polygonOptions,
            });
        }
        if (!showHeatMap.show) {
            setMarkers(data);
        }
        if (circle) {
            circleRef.current = new AMap.Circle({
                center: mapOptions.center,
                strokeColor: '#00a5e6',
                strokeOpacity: 1,
                strokeWeight: 2,
                fillColor: '#bbd4e3',
                fillOpacity: 0.35, //填充透明度
            });
            setCircle(distance);
        }
        loadedCallBack && loadedCallBack(map);
    };
    function setCircle(distance) {
        circleRef.current.setRadius(distance);
        mapEle.current.add(circleRef.current);
        // mapEle.current.setFitView([circleRef.current, ...markersEle.current]);
        mapEle.current.setFitView();
    }
    useEffect(() => {
        if (mapEle.current) {
            clearMap();
            init(mapEle.current, data);
        }
    }, [mapEle.current, data]);
    useImperativeHandle(ref, () => {
        return {
            setInfoWindow,
            clearMap,
        };
    });
    return (_jsxs("div", Object.assign({ className: style['map-container'] }, { children: [_jsx(GDMap, Object.assign({ aMapLoca: true, aMapUI: true, containerClass: style['map-container'], options: mapOptions, loadedCallBack: onMapLoaded }, { children: _jsx(HeatMapLayer, { data: data, open: showHeatMap.show, heatmapOptions: {
                        zIndex: 11,
                        radius: 50,
                        opacity: [0, 0.8],
                        gradient: {
                            0.5: 'blue',
                            0.65: 'rgb(117,211,248)',
                            0.7: 'rgb(0, 255, 0)',
                            0.9: '#ffea00',
                            1.0: 'red',
                        },
                    } }) })), _jsxs("ul", Object.assign({ className: style['map_action'] }, { children: [isHeatMap && (_jsx("li", Object.assign({ onClick: toggleHeatMap, className: style['switch_style'], style: { listStyle: 'none' } }, { children: showHeatMap.show ? '点聚合' : '热力图' }))), isMapStyle && (_jsx("li", Object.assign({ onClick: setStyle, className: style['hot_style'], style: { listStyle: 'none' } }, { children: styleStatus ? '标准' : '炫黑' }))), isZoomMap && (_jsxs("li", Object.assign({ className: style['too-bar'] }, { children: [_jsx("p", Object.assign({ onClick: () => setMapView('add') }, { children: "+" })), _jsx("p", Object.assign({ onClick: () => setMapView('sub') }, { children: "-" }))] })))] }))] })));
});
function drawBounds({ map, adcode, district, polygons, polygonOptions }) {
    //加载行政区划插件
    AMap.plugin('AMap.DistrictSearch', () => {
        if (!district) {
            //实例化DistrictSearch
            district = new AMap.DistrictSearch({
                zIndex: 10,
                subdistrict: 1,
                extensions: 'all',
                level: 'district',
                showbiz: false, // 最后一级返回街道信息
            });
        }
        //行政区查询
        district.search(adcode, function (_status, result) {
            map.remove(polygons); //清除上次结果
            polygons = [];
            if (isEmpty(result)) {
                return;
            }
            const bounds = result.districtList[0].boundaries;
            if (bounds) {
                for (let i = 0, l = bounds.length; i < l; i++) {
                    //生成行政区划polygon
                    const polygon = new AMap.Polygon(Object.assign({ strokeWeight: 1, path: bounds[i], fillOpacity: 0.4, fillColor: '#80d8ff', strokeColor: '#0091ea' }, polygonOptions));
                    polygons.push(polygon);
                }
            }
            map.add(polygons);
            map.setFitView(polygons); //视口自适应
        });
    });
}