"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const React = tslib_1.__importStar(require("react"));
const uikit_1 = require("@gravity-ui/uikit");
const debounce_1 = tslib_1.__importDefault(require("lodash/debounce.js"));
const localeContext_1 = require("../../../gravity-blocks/context/localeContext/index.js");
const mapsContext_1 = require("../../../gravity-blocks/context/mapsContext/mapsContext.js");
const mobileContext_1 = require("../../../gravity-blocks/context/mobileContext/index.js");
const utils_1 = require("../../../utils/index.js");
const ErrorWrapper_1 = tslib_1.__importDefault(require("../../ErrorWrapper/ErrorWrapper.js"));
const helpers_1 = require("../helpers.js");
const YMap_1 = require("./YMap.js");
const YandexMapApiLoader_1 = require("./YandexMapApiLoader.js");
const i18n_1 = require("./i18n/index.js");
const b = (0, utils_1.block)('map');
const DEFAULT_CONTAINER_ID = 'ymap';
const DEFAULT_ZOOM = 9;
// Center - is a required parameter for creating a new map
// We use this init center to create a map
// The real center of the map will be calculated later, using the coordinates of the markers
const INITIAL_CENTER = [0, 0];
const BALLOON_DISABLING_MARKER_OPTIONS = {
    cursor: 'drag',
    interactivityModel: 'default#silent',
};
// Helper function to convert YMapMarker to Schema.org Place object
const markerToSchemaPlace = (marker) => {
    return {
        '@type': 'Place',
        address: marker.address
            ? {
                '@type': 'Text',
                '@value': marker.address,
            }
            : undefined,
        geo: marker.coordinate && marker.coordinate.length === 2
            ? {
                '@type': 'GeoCoordinates',
                latitude: marker.coordinate[0],
                longitude: marker.coordinate[1],
            }
            : undefined,
    };
};
const YandexMap = (props) => {
    const { markers, zoom, id, disableControls = false, disableBalloons = false, areaMargin, copyrightPosition, className, forceAspectRatio = true, } = props;
    const { apiKey, scriptSrc, nonce } = React.useContext(mapsContext_1.MapsContext);
    const isMobile = React.useContext(mobileContext_1.MobileContext);
    const { lang = 'ru' } = React.useContext(localeContext_1.LocaleContext);
    const containerId = `${DEFAULT_CONTAINER_ID}-${id}`;
    const [ymap, setYmaps] = React.useState(null);
    const [height, setHeight] = React.useState(undefined);
    const ref = React.useRef(null);
    const [loading, setLoading] = React.useState(false);
    const [ready, setReady] = React.useState(false);
    const [attemptsIndex, setAttemptsIndex] = React.useState(0);
    const onTryAgain = React.useCallback(() => {
        setAttemptsIndex(attemptsIndex + 1);
    }, [attemptsIndex]);
    React.useEffect(() => {
        (async function () {
            setLoading(true);
            await YandexMapApiLoader_1.YMapsApiLoader.loadApi(apiKey, scriptSrc, lang, nonce);
            window.ymaps?.ready(() => {
                setYmaps(new YMap_1.YMap(new window.ymaps.Map(containerId, {
                    center: INITIAL_CENTER,
                    zoom: zoom || DEFAULT_ZOOM,
                    controls: disableControls ? [] : undefined,
                }, {
                    autoFitToViewport: 'always',
                    suppressMapOpenBlock: disableControls,
                    yandexMapDisablePoiInteractivity: disableControls,
                    copyrightPosition,
                }), ref.current));
            });
            setLoading(false);
        })();
    }, [
        apiKey,
        lang,
        scriptSrc,
        containerId,
        zoom,
        nonce,
        attemptsIndex,
        setLoading,
        disableControls,
        copyrightPosition,
    ]);
    React.useEffect(() => {
        if (!forceAspectRatio) {
            return;
        }
        const updateSize = (0, debounce_1.default)(() => {
            if (ref.current) {
                setHeight(Math.round((0, helpers_1.getMapHeight)(ref.current.offsetWidth, isMobile)));
            }
        }, 100);
        updateSize();
        window.addEventListener('resize', updateSize, { passive: true });
        // eslint-disable-next-line consistent-return
        return () => {
            window.removeEventListener('resize', updateSize);
        };
    }, [isMobile, forceAspectRatio]);
    React.useEffect(() => {
        if (ymap) {
            // show with computed center and placemarks
            const showPlacemarks = async () => {
                const privateMarkers = disableBalloons
                    ? markers.map(({ label, ...marker }) => ({
                        ...marker,
                        label: { ...label, ...BALLOON_DISABLING_MARKER_OPTIONS },
                    }))
                    : markers;
                await ymap.showPlacemarks({ markers: privateMarkers, zoom, areaMargin });
                setReady(true);
            };
            showPlacemarks();
        }
    }, [ymap, markers, zoom, disableBalloons, areaMargin]);
    const mapMicrodataScript = React.useMemo(() => {
        if (!markers.length) {
            return null;
        }
        const places = markers
            .filter((marker) => marker.address || marker.coordinate)
            .map(markerToSchemaPlace);
        if (places.length === 0) {
            return null;
        }
        const json = JSON.stringify({
            '@context': 'https://schema.org',
            '@graph': places,
        });
        return (0, jsx_runtime_1.jsx)("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: json } });
    }, [markers]);
    if (!markers)
        return null;
    return ((0, jsx_runtime_1.jsx)(ErrorWrapper_1.default, { isError: YandexMapApiLoader_1.YMapsApiLoader.status === YandexMapApiLoader_1.MapApiStatus.Error, text: (0, i18n_1.i18n)('map-load-error'), buttonText: (0, i18n_1.i18n)('map-try-again'), handler: onTryAgain, className: b('wrapper'), children: (0, jsx_runtime_1.jsxs)("div", { className: b('wrapper'), children: [mapMicrodataScript, (0, jsx_runtime_1.jsx)("div", { id: containerId, className: b({ hidden: !ready }, className), ref: ref, style: { height } }), loading ? (0, jsx_runtime_1.jsx)(uikit_1.Spin, { size: "xl", className: b('spinner') }) : null] }) }));
};
exports.default = YandexMap;
//# sourceMappingURL=YandexMap.js.map
