"use strict";
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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReltioMap = void 0;
var react_1 = __importStar(require("react"));
var ramda_1 = require("ramda");
var react_google_maps_1 = require("@vis.gl/react-google-maps");
var TopRightMapControls_1 = require("./components/TopRightMapControls");
var TopCenterMapControls_1 = require("./components/TopCenterMapControls");
var helpers_1 = require("./helpers");
var constants_1 = require("../constants");
var useFitMapBounds_1 = require("./useFitMapBounds");
var styles_1 = require("./styles");
var ClusteredMarkers_1 = require("./components/ClusteredMarkers");
var Polygon_1 = require("./components/Polygon");
var DrawingManager_1 = require("./components/DrawingManager");
var ON_MAP_MOVE_DEBOUNCE_INTERVAL = 1000;
var libraries = ['drawing'];
var ReltioMap = function (_a) {
    var mapKey = _a.mapKey, restProps = __rest(_a, ["mapKey"]);
    return (react_1.default.createElement(react_google_maps_1.APIProvider, { apiKey: mapKey, libraries: libraries },
        react_1.default.createElement(InternalReltioMap, __assign({}, restProps))));
};
exports.ReltioMap = ReltioMap;
var emptyObject = {};
var emptyArray = [];
var InternalReltioMap = (0, react_1.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.drawingModes, drawingModes = _d === void 0 ? emptyArray : _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 ? ramda_1.identity : _g, _h = _a.onOverlayUpdated, onOverlayUpdated = _h === void 0 ? ramda_1.identity : _h, _j = _a.onMarkerClicked, onMarkerClicked = _j === void 0 ? ramda_1.identity : _j;
    var styles = (0, styles_1.useStyles)();
    var mapMoveEndTimer = (0, react_1.useRef)(null);
    var isLoaded = (0, react_google_maps_1.useApiIsLoaded)();
    var map = (0, react_google_maps_1.useMap)();
    var _k = (0, react_1.useState)(null), polygon = _k[0], setPolygon = _k[1];
    var _l = (0, react_1.useState)(null), drawingMode = _l[0], setDrawingMode = _l[1];
    (0, useFitMapBounds_1.useFitMapBounds)({ markers: markers, activeOverlay: activeOverlay, map: map, isSearchOnMapMove: isSearchOnMapMove });
    var allOverlayOptions = (0, react_1.useMemo)(function () { return (__assign(__assign({}, constants_1.DEFAULT_OVERLAY_OPTIONS), overlayOptions)); }, [overlayOptions]);
    var googleMapOptions = (0, react_1.useMemo)(function () { return (__assign(__assign({}, constants_1.DEFAULT_GOOGLE_MAP_OPTIONS), mapOptions)); }, [mapOptions]);
    var drawingManagerOptions = (0, react_1.useMemo)(function () { return ({
        drawingControl: false,
        polygonOptions: allOverlayOptions
    }); }, [allOverlayOptions]);
    var polygonOptions = (0, react_1.useMemo)(function () { return (__assign({ paths: activeOverlay === null || activeOverlay === void 0 ? void 0 : activeOverlay.path, editable: true }, allOverlayOptions)); }, [activeOverlay, allOverlayOptions]);
    var handleChangeIsSearchOnMapMove = (0, react_1.useCallback)(function (isSearchOnMapMove) {
        onMapBoundsChanged(isSearchOnMapMove ? (0, helpers_1.getMapBoundsPolygon)(map) : null);
        setDrawingMode(null);
        clearTimeout(mapMoveEndTimer.current);
    }, [map, onMapBoundsChanged]);
    var handleMapMoveStart = (0, react_1.useCallback)(function () {
        clearTimeout(mapMoveEndTimer.current);
    }, []);
    var handleMapMoveEnd = (0, react_1.useCallback)(function () {
        if (!isSearchOnMapMove)
            return;
        onMapBoundsChanged((0, helpers_1.getMapBoundsPolygon)(map));
    }, [isSearchOnMapMove, map, onMapBoundsChanged]);
    var handleMapIdle = (0, react_1.useCallback)(function () {
        if (!isSearchOnMapMove)
            return;
        clearTimeout(mapMoveEndTimer.current);
        mapMoveEndTimer.current = setTimeout(handleMapMoveEnd, ON_MAP_MOVE_DEBOUNCE_INTERVAL);
    }, [handleMapMoveEnd, isSearchOnMapMove]);
    var handleOverlayChange = (0, react_1.useCallback)(function (_e, propOverlay) {
        var _a;
        var _b;
        var polygonStateOverlay = polygon && { type: constants_1.MAP_DRAWING_MODES.POLYGON, overlay: polygon };
        var stateOverlay = propOverlay || polygonStateOverlay;
        if ((0, ramda_1.isEmpty)(stateOverlay))
            return;
        var overlay = stateOverlay.overlay, type = stateOverlay.type;
        var getPolygonLatLngCoordinates = function () {
            return overlay
                .getPath()
                .getArray()
                .map(function (latlng) { return [latlng.lat(), latlng.lng()]; });
        };
        var getCircleParameters = function () { return ({
            radius: overlay.getRadius() / 1000,
            center: overlay.getCenter()
        }); };
        var typeActions = (_a = {},
            _a[constants_1.MAP_DRAWING_MODES.POLYGON] = getPolygonLatLngCoordinates,
            _a[constants_1.MAP_DRAWING_MODES.CIRCLE] = getCircleParameters,
            _a);
        var data = (_b = typeActions[type]) === null || _b === void 0 ? void 0 : _b.call(typeActions);
        if (!data)
            return;
        onOverlayUpdated({ data: data, type: type });
    }, [onOverlayUpdated, polygon]);
    var handleOverlayComplete = (0, react_1.useCallback)(function (type) { return function (overlay) {
        handleOverlayChange(null, { type: type, overlay: overlay });
        overlay.setMap(null);
        setDrawingMode(null);
    }; }, [handleOverlayChange]);
    var handleClearOverlay = (0, react_1.useCallback)(function () {
        onOverlayUpdated(null);
    }, [onOverlayUpdated]);
    if (!isLoaded) {
        return loadingElement;
    }
    var shouldRenderDrawingManager = isSearchEnabled && Boolean(drawingModes.length);
    var shouldRenderRightMapControls = map && isSearchEnabled && Boolean(drawingModes.length);
    var shouldRenderCenterMapControls = map && isSearchEnabled;
    var shouldRenderPolygon = !(0, helpers_1.getDrawingMode)(drawingMode) && activeOverlay && (0, ramda_1.propEq)('type', constants_1.MAP_DRAWING_MODES.POLYGON, activeOverlay);
    return (react_1.default.createElement(react_google_maps_1.Map, __assign({ mapId: mapId || 'mapId' }, googleMapOptions, { defaultZoom: defaultZoom, defaultCenter: defaultCenter, onZoomChanged: handleMapMoveStart, onDragstart: handleMapMoveStart, onIdle: handleMapIdle, className: mapContainerClassName }),
        shouldRenderRightMapControls && (react_1.default.createElement(react_google_maps_1.MapControl, { position: react_google_maps_1.ControlPosition.TOP_RIGHT },
            react_1.default.createElement(TopRightMapControls_1.TopRightMapControls, { className: styles.mapControlContainer, hasActiveOverlay: !!activeOverlay, drawingModes: drawingModes, drawingMode: drawingMode, onDrawingModeChanged: setDrawingMode, onClearOverlay: handleClearOverlay }))),
        shouldRenderCenterMapControls && (react_1.default.createElement(react_google_maps_1.MapControl, { position: react_google_maps_1.ControlPosition.TOP_CENTER },
            react_1.default.createElement(TopCenterMapControls_1.TopCenterMapControls, { className: styles.mapControlContainer, onChangeIsSearchOnMapMove: handleChangeIsSearchOnMapMove, isSearchOnMapMove: isSearchOnMapMove }))),
        react_1.default.createElement(ClusteredMarkers_1.ClusteredMarkers, { entityMarkers: markers, enabledClustering: markerClusterer, options: markerClustererOptions, onMarkerClick: onMarkerClicked }),
        shouldRenderPolygon && (react_1.default.createElement(Polygon_1.Polygon, { onInit: setPolygon, options: polygonOptions, onMouseUp: handleOverlayChange, onDragEnd: handleOverlayChange })),
        shouldRenderDrawingManager && (react_1.default.createElement(DrawingManager_1.DrawingManager, { onPolygonComplete: handleOverlayComplete(constants_1.MAP_DRAWING_MODES.POLYGON), onCircleComplete: handleOverlayComplete(constants_1.MAP_DRAWING_MODES.CIRCLE), drawingMode: (0, helpers_1.getDrawingMode)(drawingMode), options: drawingManagerOptions }))));
});
InternalReltioMap.displayName = 'InternalReltioMap';
