"use strict";
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NamedPlaceChooser = void 0;
const React = __importStar(require("react"));
const react_dom_1 = require("react-dom");
const react_spinner_1 = __importDefault(require("react-spinner"));
const ReactContext_1 = __importDefault(require("../../../ReactContext"));
const MapArrayField_1 = require("../MapArrayField");
const globals_1 = require("@luomus/laji-map/lib/globals");
const SelectWidget_1 = require("../../widgets/SelectWidget");
const Popup_1 = require("./Popup");
const memoizee_1 = __importDefault(require("memoizee"));
class NamedPlaceChooser extends React.Component {
    constructor(props) {
        super(props);
        this.popupRef = React.createRef();
        this.popupContainerRef = React.createRef();
        this.mapRef = React.createRef();
        this.onPlaceSelected = (place) => {
            this.props.onSelected(place);
        };
        this.onPlaceDeleted = (place) => {
            const onDelete = () => {
                this.mapRef.current.map.map.closePopup();
                this.setState({ deleting: false, popupIdx: undefined });
            };
            this.setState({ deleting: true });
            this.props.onDeleted(place, onDelete);
        };
        this.onSelectChange = (idx) => {
            if (idx === undefined) {
                return;
            }
            const { map } = this.mapRef.current;
            const layers = this.idxToLayer[idx];
            const [layer] = layers;
            const bounds = map.getBoundsForLayers(layers);
            const center = bounds.getCenter();
            map.fitBounds(bounds, { animate: false });
            layer.fire("click", { latlng: center });
        };
        this.getFeatureStyle = (data) => {
            const { feature = {} } = data || {};
            function getColor(idx) {
                const r = globals_1.NORMAL_COLOR.substring(1, 3);
                const g = globals_1.NORMAL_COLOR.substring(3, 5);
                const b = globals_1.NORMAL_COLOR.substring(5, 7);
                return [r, g, b].reduce((rgb, hex) => {
                    const decimal = parseInt(hex, 16);
                    const amount = 40;
                    const _decimal = (idx % 2) ? decimal : Math.min(decimal + amount, 255);
                    return rgb + _decimal.toString(16);
                }, "#");
            }
            const { idx } = feature.properties || {};
            const color = idx === this.state.popupIdx ? globals_1.ACTIVE_COLOR : getColor(idx);
            return { color, fillColor: color };
        };
        this.getPopup = ({ feature }, givePopupToLajiMap) => {
            const { elem, button } = this.popupRef.current;
            const { idx } = feature.properties;
            this.setState({ popupIdx: idx });
            givePopupToLajiMap(elem);
            this.props.formContext.setTimeout(() => (0, react_dom_1.findDOMNode)(button).focus());
        };
        this.onPopupClose = () => {
            this.popupContainerRef.current.appendChild((0, react_dom_1.findDOMNode)(this.popupRef.current.elem));
        };
        this.getEnumOptions = (0, memoizee_1.default)((places, translations) => ({
            placeholder: `${translations.SelectPlaceFromList}...`,
            enumOptions: (places || []).map((place, idx) => {
                return { value: idx, label: place.name };
            })
        }));
        this.state = {};
    }
    componentDidUpdate(_, prevState) {
        const { map } = this.mapRef.current;
        this.idxToLayer = map.data.reduce((idxToLayer, item) => {
            const layerGroup = item.group;
            layerGroup.eachLayer((layer) => {
                if (!idxToLayer[layer.feature.properties.idx]) {
                    idxToLayer[layer.feature.properties.idx] = [];
                }
                idxToLayer[layer.feature.properties.idx].push(layer);
            });
            return idxToLayer;
        }, {});
        if (this.state.popupIdx !== prevState.popupIdx) {
            const prevLayers = this.idxToLayer[prevState.popupIdx] || [];
            const layers = this.idxToLayer[this.state.popupIdx] || [];
            [prevLayers, layers].forEach(layers => {
                layers.forEach((layer) => {
                    if (layer) {
                        map.setLayerStyle(layer, this.getFeatureStyle({ feature: layer.feature }));
                    }
                });
            });
        }
    }
    render() {
        const { places, failed, formContext: { translations } } = this.props;
        const { Alert } = this.context.theme;
        if (failed) {
            return React.createElement(Alert, { variant: "danger" }, `${translations.NamedPlacesFetchFail} ${translations.TryAgainLater}`);
        }
        else {
            let pointer = 1;
            const data = (places || []).reduce((data, place, i) => {
                const { geometry } = place;
                let isCollection = false;
                if (geometry.type === "GeometryCollection") {
                    isCollection = true;
                }
                if (isCollection) {
                    data[pointer] = {
                        geoData: { type: "FeatureCollection", features: geometry.geometries.map((geom) => { return { type: "Feature", geometry: geom, properties: { idx: i } }; }) },
                        getFeatureStyle: this.getFeatureStyle,
                        getPopup: this.getPopup,
                        highlightOnHover: true
                    };
                    pointer++;
                }
                else {
                    if (!data[0])
                        data[0] = {
                            geoData: { type: "FeatureCollection", features: [] },
                            getFeatureStyle: this.getFeatureStyle,
                            getPopup: this.getPopup,
                            cluster: true,
                            highlightOnHover: true
                        };
                    data[0].geoData.features.push({ type: "Feature", geometry, properties: { idx: i } });
                }
                return data;
            }, []);
            return (React.createElement("div", { style: { height: "inherit" } },
                React.createElement(SelectWidget_1.SearchableDrowndown, { value: this.state.popupIdx, disabled: !places, options: this.getEnumOptions(places, translations), onChange: this.onSelectChange, selectOnChange: false, includeEmpty: true, id: "named-place-chooser-select", formContext: this.props.formContext }),
                React.createElement(MapArrayField_1.Map, { ref: this.mapRef, data: data, markerPopupOffset: 45, featurePopupOffset: 5, controls: { draw: false }, lang: this.props.formContext.lang, bodyAsDialogRoot: false, formContext: this.props.formContext, onPopupClose: this.onPopupClose }),
                (!places) ? React.createElement(react_spinner_1.default, null) : null,
                React.createElement("div", { style: { display: "none" }, ref: this.popupContainerRef },
                    React.createElement(Popup_1.Popup, { ref: this.popupRef, place: (places || [])[this.state.popupIdx], onPlaceSelected: this.onPlaceSelected, onPlaceDeleted: this.onPlaceDeleted, deleting: this.state.deleting, translations: translations }))));
        }
    }
}
exports.NamedPlaceChooser = NamedPlaceChooser;
NamedPlaceChooser.contextType = ReactContext_1.default;
