import React, { useRef, useState, useEffect } from 'react';
import './Map.css';
import MapContext from './MapContext';
import * as ol from 'ol';
import { DragRotateAndZoom, defaults as defaultInteractions, Select as OlSelect } from 'ol/interaction';
import { Style as OlStyle, Icon as OlIcon } from 'ol/style';
import { click as olClick } from 'ol/events/condition';
import GeoLocation from '../geoLocation/GeoLocation';
import { fromLonLat } from 'ol/proj';
import { usePrevious } from '../../utilities/usePrevious';
import { last } from 'lodash-es';
export const Map = ({ children, zoom, center, projection, addInteractions, sendSelected, sendType, SelectedPin, changeLat, changeLong, setPosition, width, height, addressBar, popoverOverlayProps, additionalOnclickFeature, popoverRef, setSelectInteraction, setPopoverOverlay, setMapObject }) => {
    const mapRef = useRef();
    const [map, setMap] = useState(null);
    const [selected, setSelected] = useState();
    const [markingType, setMarkingType] = useState();
    const [count, setCount] = useState(0);
    const [mapClicked, setMapclicked] = useState(false);
    const prevCount = usePrevious(count);
    // on component mount
    useEffect(() => {
        const options = {
            view: new ol.View({
                center: fromLonLat(center),
                zoom,
                projection
            }),
            interactions: defaultInteractions().extend([new DragRotateAndZoom()]),
            layers: [],
            controls: [],
            overlays: []
        };
        const mapObject = new ol.Map(options);
        mapObject.setTarget(mapRef.current);
        let popoverOverlay;
        if (popoverRef) {
            popoverOverlay = new ol.Overlay(Object.assign({ element: popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current, autoPan: true }, popoverOverlayProps));
            mapObject.addOverlay(popoverOverlay);
            if (setPopoverOverlay) {
                setPopoverOverlay(popoverOverlay);
            }
        }
        setMap(mapObject);
        if (setMapObject) {
            setMapObject(mapObject);
        }
        const pointSelect = new OlSelect({
            condition: (e) => {
                return olClick(e);
            },
            filter: (f) => {
                if (f.getGeometry().getType() === 'Point') {
                    return true;
                }
            },
            multi: true,
            hitTolerance: 10,
            style: new OlStyle({
                image: new OlIcon({
                    anchor: [0.5, 48],
                    anchorXUnits: 'fraction',
                    anchorYUnits: 'pixels',
                    src: SelectedPin
                })
            })
        });
        pointSelect.on('select', (e) => {
            var _a;
            const currentFeature = last(e.selected);
            const currentFeaturesProperties = currentFeature === null || currentFeature === void 0 ? void 0 : currentFeature.getProperties();
            if (popoverOverlay && (popoverRef === null || popoverRef === void 0 ? void 0 : popoverRef.current) && currentFeaturesProperties) {
                popoverOverlay.setPosition(currentFeature === null || currentFeature === void 0 ? void 0 : currentFeature.getGeometry().getCoordinates());
            }
            if (additionalOnclickFeature &&
                (!currentFeaturesProperties ||
                    (currentFeaturesProperties &&
                        ((_a = Object.keys(currentFeaturesProperties)) === null || _a === void 0 ? void 0 : _a.length) > 1))) {
                additionalOnclickFeature(currentFeaturesProperties);
            }
        });
        mapObject.addInteraction(pointSelect);
        if (setSelectInteraction) {
            setSelectInteraction(pointSelect);
        }
        return () => mapObject.setTarget(undefined);
    }, []);
    useEffect(() => {
        sendSelected(selected);
    }, [sendSelected, selected]);
    useEffect(() => {
        sendType(markingType);
    }, [sendType, markingType]);
    const postSelected = (id, type) => {
        setSelected(id);
        setMarkingType(type);
    };
    // console.log('ID, TYPE', selected, markingType);
    // zoom change handler
    useEffect(() => {
        if (!map)
            return;
        map.getView().setZoom(zoom);
    }, [zoom]);
    // click event handler
    useEffect(() => {
        if (!map)
            return;
        map.on('click', (e) => {
            setMapclicked(true);
            map.forEachFeatureAtPixel(e.pixel, 
            // a => setSelected(a.values_.geometry.flatCoordinates[2])
            (a) => postSelected(a.values_.geometry.flatCoordinates[2], a.values_.geometry.flatCoordinates[3]));
        });
    }, [map]);
    // center change handler - Caused issue of recentering the map on each map selection when passed.
    useEffect(() => {
        if (!map)
            return;
        setCount(zoom);
        if (zoom === prevCount && !mapClicked) {
            map.getView().setCenter(center);
        }
    }, [center]);
    useEffect(() => {
        if (!map)
            return;
        if (!mapClicked) {
            map.getView().setCenter(center);
        }
    }, [map]);
    useEffect(() => {
        if (!map)
            return;
        map.getview().getprojection(projection);
    }, [projection]);
    return (React.createElement(MapContext.Provider, { value: { map } }, addressBar && (React.createElement("div", { style: { marginLeft: 35, marginTop: -6 } }, React.createElement(GeoLocation
    // sendSelected={setCenter}
    , { 
        // sendSelected={setCenter}
        center: center, changeLat: changeLat, changeLong: changeLong, setPosition: setPosition }))), React.createElement("div", { ref: mapRef, style: { height: height || '85vh', width: width } }, children)));
};
//# sourceMappingURL=Map.js.map