var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import React, { memo, useCallback, useMemo, useRef, useState } from 'react';
import { propEq, isEmpty, identity } from 'ramda';
import { APIProvider, ControlPosition, Map, MapControl, useApiIsLoaded, useMap } from '@vis.gl/react-google-maps';
import { TopRightMapControls } from './components/TopRightMapControls';
import { TopCenterMapControls } from './components/TopCenterMapControls';
import { getMapBoundsPolygon, isActivePolygonDrawing } from './helpers';
import { DEFAULT_GOOGLE_MAP_OPTIONS, DEFAULT_OVERLAY_OPTIONS, POLYGON_DRAWING_MODE } from '../constants';
import { useFitMapBounds } from './useFitMapBounds';
import { ClusteredMarkers } from './components/ClusteredMarkers';
import { Polygon } from './components/Polygon';
import { PolygonDrawing } from './components/PolygonDrawing';
import { useStyles } from './styles';
var ON_MAP_MOVE_DEBOUNCE_INTERVAL = 1000;
var libraries = ['marker'];
export var ReltioMap = function (_a) {
    var mapKey = _a.mapKey, restProps = __rest(_a, ["mapKey"]);
    return (React.createElement(APIProvider, { apiKey: mapKey, libraries: libraries },
        React.createElement(InternalReltioMap, __assign({}, restProps))));
};
var emptyObject = {};
var emptyArray = [];
var InternalReltioMap = memo(function (_a) {
    var mapId = _a.mapId, _b = _a.markers, markers = _b === void 0 ? emptyArray : _b, defaultZoom = _a.defaultZoom, defaultCenter = _a.defaultCenter, loadingElement = _a.loadingElement, isSearchOnMapMove = _a.isSearchOnMapMove, isSearchEnabled = _a.isSearchEnabled, activeOverlay = _a.activeOverlay, _c = _a.overlayOptions, overlayOptions = _c === void 0 ? emptyObject : _c, _d = _a.enablePolygonDrawing, enablePolygonDrawing = _d === void 0 ? false : _d, markerClusterer = _a.markerClusterer, markerClustererOptions = _a.markerClustererOptions, _f = _a.mapOptions, mapOptions = _f === void 0 ? emptyObject : _f, mapContainerClassName = _a.mapContainerClassName, _g = _a.onMapBoundsChanged, onMapBoundsChanged = _g === void 0 ? identity : _g, _h = _a.onOverlayUpdated, onOverlayUpdated = _h === void 0 ? identity : _h, _j = _a.onMarkerClicked, onMarkerClicked = _j === void 0 ? identity : _j;
    var styles = useStyles();
    var mapMoveEndTimer = useRef(null);
    var isLoaded = useApiIsLoaded();
    var map = useMap();
    var _k = useState(null), polygon = _k[0], setPolygon = _k[1];
    var _l = useState(null), drawingMode = _l[0], setDrawingMode = _l[1];
    useFitMapBounds({ markers: markers, activeOverlay: activeOverlay, map: map, isSearchOnMapMove: isSearchOnMapMove });
    var allOverlayOptions = useMemo(function () { return (__assign(__assign({}, DEFAULT_OVERLAY_OPTIONS), overlayOptions)); }, [overlayOptions]);
    var googleMapOptions = useMemo(function () { return (__assign(__assign({}, DEFAULT_GOOGLE_MAP_OPTIONS), mapOptions)); }, [mapOptions]);
    var previewPolylineOptions = useMemo(function () {
        var _a;
        return ({
            strokeColor: allOverlayOptions.strokeColor,
            strokeWeight: allOverlayOptions.strokeWeight,
            zIndex: ((_a = allOverlayOptions.zIndex) !== null && _a !== void 0 ? _a : 1) + 1
        });
    }, [allOverlayOptions]);
    var completedPolygonDrawingOptions = useMemo(function () { return (__assign(__assign({}, allOverlayOptions), { editable: false })); }, [allOverlayOptions]);
    var polygonOptions = useMemo(function () { return (__assign({ paths: activeOverlay === null || activeOverlay === void 0 ? void 0 : activeOverlay.path, editable: true }, allOverlayOptions)); }, [activeOverlay, allOverlayOptions]);
    var handleChangeIsSearchOnMapMove = useCallback(function (isSearchOnMapMove) {
        onMapBoundsChanged(isSearchOnMapMove ? getMapBoundsPolygon(map) : null);
        setDrawingMode(null);
        clearTimeout(mapMoveEndTimer.current);
    }, [map, onMapBoundsChanged]);
    var handleMapMoveStart = useCallback(function () {
        clearTimeout(mapMoveEndTimer.current);
    }, []);
    var handleMapMoveEnd = useCallback(function () {
        if (!isSearchOnMapMove)
            return;
        onMapBoundsChanged(getMapBoundsPolygon(map));
    }, [isSearchOnMapMove, map, onMapBoundsChanged]);
    var handleMapIdle = useCallback(function () {
        if (!isSearchOnMapMove)
            return;
        clearTimeout(mapMoveEndTimer.current);
        mapMoveEndTimer.current = setTimeout(handleMapMoveEnd, ON_MAP_MOVE_DEBOUNCE_INTERVAL);
    }, [handleMapMoveEnd, isSearchOnMapMove]);
    var handleOverlayChange = useCallback(function (_e, propOverlay) {
        var polygonStateOverlay = polygon && { type: POLYGON_DRAWING_MODE, overlay: polygon };
        var stateOverlay = propOverlay || polygonStateOverlay;
        if (isEmpty(stateOverlay))
            return;
        var overlay = stateOverlay.overlay, type = stateOverlay.type;
        var data = overlay
            .getPath()
            .getArray()
            .map(function (latlng) { return [latlng.lat(), latlng.lng()]; });
        onOverlayUpdated({ data: data, type: type });
    }, [onOverlayUpdated, polygon]);
    var onPolygonDrawingComplete = useCallback(function (overlay) {
        handleOverlayChange(null, { type: POLYGON_DRAWING_MODE, overlay: overlay });
        overlay.setMap(null);
        setDrawingMode(null);
    }, [handleOverlayChange]);
    var handleClearOverlay = useCallback(function () {
        onOverlayUpdated(null);
    }, [onOverlayUpdated]);
    if (!isLoaded) {
        return loadingElement;
    }
    var shouldRenderPolygonDrawing = isSearchEnabled && enablePolygonDrawing;
    var shouldRenderRightMapControls = map && isSearchEnabled && enablePolygonDrawing;
    var shouldRenderCenterMapControls = map && isSearchEnabled;
    var shouldRenderPolygon = !isActivePolygonDrawing(drawingMode) &&
        activeOverlay &&
        propEq('type', POLYGON_DRAWING_MODE, activeOverlay);
    return (React.createElement(Map, __assign({ mapId: mapId || 'mapId' }, googleMapOptions, { defaultZoom: defaultZoom, defaultCenter: defaultCenter, onZoomChanged: handleMapMoveStart, onDragstart: handleMapMoveStart, onIdle: handleMapIdle, className: mapContainerClassName }),
        shouldRenderRightMapControls && (React.createElement(MapControl, { position: ControlPosition.TOP_RIGHT },
            React.createElement(TopRightMapControls, { className: styles.mapControlContainer, hasActiveOverlay: !!activeOverlay, enablePolygonDrawing: enablePolygonDrawing, drawingMode: drawingMode, onDrawingModeChanged: setDrawingMode, onClearOverlay: handleClearOverlay }))),
        shouldRenderCenterMapControls && (React.createElement(MapControl, { position: ControlPosition.TOP_CENTER },
            React.createElement(TopCenterMapControls, { className: styles.mapControlContainer, onChangeIsSearchOnMapMove: handleChangeIsSearchOnMapMove, isSearchOnMapMove: isSearchOnMapMove }))),
        React.createElement(ClusteredMarkers, { entityMarkers: markers, enabledClustering: markerClusterer, options: markerClustererOptions, onMarkerClick: onMarkerClicked, disabled: isActivePolygonDrawing(drawingMode) }),
        shouldRenderPolygon && (React.createElement(Polygon, { onInit: setPolygon, options: polygonOptions, onMouseUp: handleOverlayChange, onDragEnd: handleOverlayChange })),
        shouldRenderPolygonDrawing && (React.createElement(PolygonDrawing, { isActive: isActivePolygonDrawing(drawingMode), previewPolylineOptions: previewPolylineOptions, completedPolygonOptions: completedPolygonDrawingOptions, onPolygonComplete: onPolygonDrawingComplete }))));
});
InternalReltioMap.displayName = 'InternalReltioMap';
