<template>
    <div class="tb-map" :class="{ 'tb-map--alternative-menu-style': settings.useAlternativeMenuStyle }">
        <tb-map-filter-menu
            ref="filterMenu"
            v-if="!settings.disableMenu"
            :use-alternative-menu-style="settings.useAlternativeMenuStyle"
            :lang="settings.lang"
            :items="filterItems"
            :current-filter="currentFilter"
            @activate="filter => activateFilter(filter)"
            @toggle="() => $refs.renderer.invalidateSize()"
        />

        <tb-map-renderer
            ref="renderer"
            :map-type="settings.mapType"
            :settings="settings.map"
            :markers="markers"
        >
            <template v-slot:info-window="{ marker }">
                <tb-info-window
                    :link-target="settings.linkTarget"
                    :lang="settings.lang"
                    :marker="marker"
                    @close="$refs.renderer.closeInfoWindow()"
                />
            </template>
        </tb-map-renderer>
    </div>
</template>
<script>
import merge from 'lodash/merge';
import TbMapFilterMenu from './filter/filter-menu.vue';
import { FilteredMarkerSource } from './data/filtered-marker-source';
import TbMapRenderer from './map/toubiz-map-renderer.vue';
import TbInfoWindow from './info-window.vue';
import { stripMultilineIndention } from '../common/string-utilities';

export function prepareSettings (userSettings) {
    // Start out with a default configuration object.
    const DEFAULTS = {
        mapType: 'osm',
        importers: [ { type: 'dom' } ],
        selectors: {
            filters: '[data-toubiz-map-filter-menu]',
            mapContainer: '[data-toubiz-map-container]',
        },
        map: {
            geolocation: {
                enabled: false,
                waitForUserIntent: true,
            },
        },
        linkTarget: '_self',
        markerStyle: {
            iconUrl: null,
            height: 50,
            width: 35,
            offsetX: 17.5,
            offsetY: 50,
            iconSize: 19,
        },
        centerOnMarkers: true,
        useAlternativeMenuStyle: false,
        disableMenu: false,
    };

    // Merge the specified settings with default settings.
    const settings = merge(DEFAULTS, userSettings);

    // Normalize initial zoom level from google-maps style to 0-100
    if (settings.map.zoom && settings.map.zoom <= 18) {
        const zoom = settings.map.zoom * 100 / 18;
        console.warn(stripMultilineIndention(`
            ## Toubiz Map deprecation notice
            Detected an initial zoom level <= 18 (${settings.map.zoom}) and assumed gmaps scaled values (1-12).
            Automatically transformed it to ${zoom} - Please update your markup to provide values from 0-100.
        `));
        settings.map.zoom = zoom || 80;
    }

    return settings;
}

export default {
    components: { TbInfoWindow, TbMapRenderer, TbMapFilterMenu },
    props: {
        settings: { type: Object, required: true },
    },

    data: () => ({
        markerSource: null,

        markers: [],
        currentFilter: null,
        filterItems: [],
    }),

    async created() {
        this.markerSource = new FilteredMarkerSource({
            defaultMarkerStyle: this.settings.markerStyle,
            importers: this.settings.importers,
        });

        this.markerSource.filteredMarkers(markers => this.$set(this, 'markers', markers));
        this.markerSource.currentFilter(filter => this.$set(this, 'currentFilter', filter));
        this.markerSource.allFilterItems(items => this.$set(this, 'filterItems', items));
        this.markerSource.allMarkers(() => this.centerMapOnMarkersIfConfigured());

        await this.markerSource.importData();
        this.centerMapOnMarkersIfConfigured();
    },

    mounted() {
        if (
            this.$refs.filterMenu
            && this.settings.openMenuInitially
            && window.innerWidth > 600
        ) {
            this.$refs.filterMenu.toggleOpenState(true);
        }
    },

    methods: {
        activateFilter(filter) {
            this.markerSource.setCurrentFilter(filter);
            this.centerMapOnMarkersIfConfigured();
        },

        centerMapOnMarkersIfConfigured() {
            if (this.settings.centerOnMarkers && this.$refs.renderer) {
                this.$refs.renderer.centerMapOnMarkers();
            }
        },
    },
};
</script>

