import { stripMultilineIndention } from '../../common/string-utilities';
import { parseStringAsDom } from '@nimius/dom-utility';
import { GoogleMapsStatic } from './static/google-maps-static';
import { MapToolkitStatic } from './static/map-toolkit-static';
import { StaticDynamicMapSwitcher } from './static/static-dynamic-map-switcher';

function loadGoogleMap() {
    return import('./google-maps/google-map').then(mod => mod.GoogleMap);
}

function loadToursprung() {
    return import('./maptoolkit/map-toolkit').then(mod => mod.MapToolkit);
}

function loadLeaflet() {
    return import('./leaflet/leaflet').then(mod => mod.Leaflet);
}


const implementations = {
    'google-maps': (mapContainer, options) => loadGoogleMap().then(GoogleMap => new GoogleMap(mapContainer, options)),
    toursprung: (mapContainer, options) => loadToursprung().then(MapToolkit => new MapToolkit(mapContainer, options)),
    osm: (mapContainer, options) => loadLeaflet().then(Leaflet => new Leaflet(mapContainer, options)),
    'google-maps-static': (mapContainer, options) => new GoogleMapsStatic(mapContainer, options),
    'toursprung-static': (mapContainer, options) => new MapToolkitStatic(mapContainer, options),
    'static-dynamic-switch': (mapContainer, options) => new StaticDynamicMapSwitcher(mapContainer, options),
};

/**
 * @param {string} type
 * @param {HTMLElement} mapContainer
 * @param {AbstractMapWithMarkers~Options} options
 * @param {string} fallbackType
 * @returns {AbstractMapWithMarkers}
 */
export async function initializeMap(type, mapContainer, options, fallbackType = 'osm') {
    options = options || {};
    if (!implementations[type]) {
        console.warn(stripMultilineIndention(`
            mapType '${type}' unknown. Using '${fallbackType}'.
            Valid mapTypes are [${Object.keys(implementations).join(', ')}]
        `));
        type = fallbackType;
    }

    const map = await implementations[type](mapContainer, options);
    await map.initialize();
    return map;
}

/**
 * @param {AbstractMapWithMarkers} map
 */
export function setupAutomaticClickHandling(map) {
    map.onMarkerClick(marker => {
        if (marker.tour && marker.tour.polygon && marker.tour.polygon.length > 0 && map.drawTourOntoMap) {
            map.drawTourOntoMap(marker, false);
        }
        if (marker.contentRenderer && map.openInfoWindow) {
            marker._markerDom = parseStringAsDom(marker.contentRenderer())[0];
            map.openInfoWindow(marker, marker._markerDom);

            const closeButtons = marker._markerDom
                .querySelectorAll('[data-toubiz-map-info-window-close-button]');
            for (const closeButton of closeButtons) {
                closeButton.addEventListener('click', () => map.closeInfoWindow());
            }
        }
    });
}
