<template>
    <div class="map-wrap">
        <div id="map" class="map" ref="mapContainer"></div>
    </div>
</template>


<script>
import maplibregl from "maplibre-gl";
import { markRaw, onMounted, onUnmounted, reactive, shallowRef, watch } from "vue";
export default {
    name: "map-component",
    props: {
        idlist: {
            type: Array,
            required: true,
        }
    },
    setup(props, context) {
        const mapContainer = shallowRef(null);
        const map = shallowRef(null);
        let currentFadr = reactive({ "fadr": [] });

        const apiKey = "pk.eyJ1IjoiZ2hlcm1hbnQiLCJhIjoiY2pncDUwcnRmNDQ4ZjJ4czdjZXMzaHZpNyJ9.3rFyYRRtvLUngHm027HZ7A";


        watch(()=> [...props.idlist], (_currentValue, _oldValue) => {
            updateSamplesLayer()
        });

        const buildMap = () => {
            const initialState = { lng: 37.625, lat: 55.751, zoom: 5 };

            map.value = markRaw(new maplibregl.Map({
                container: mapContainer.value, // container id
                // DOCS: https://maplibre.org/maplibre-gl-js-docs/style-spec/
                style: {
                    version: 8,
                    sources: {},
                    layers: []
                },
                center: [37.625, 55.751], // starting position [lng, lat]
                zoom: 2, // starting zoom
                maxZoom: 10
            }));

            map.value.on('load', () => {
                map.value.addSource('countries', {
                    'type': 'vector',
                    "tiles": [`https://api.mapbox.com/v4/ghermant.aq1p7k29/{z}/{x}/{y}.mvt?access_token=${apiKey}`]
                });

                map.value.addLayer(
                    {
                        'id': 'countries-layer',
                        'type': 'line',
                        'source': 'countries',
                        'source-layer': 'ne_110m_admin_0_countries-cz6wwp',
                        'paint': {
                            "line-color": "blue",
                            "line-width": 3
                        },
                        'filter': ["==", ["get", "NAME"], "Russia"],
                        "maxzoom": 4
                    }
                );


                map.value.addSource('samples', {
                    'type': 'vector',
                    "tiles": ["http://localhost:8080/martin/public.geodata/{z}/{x}/{y}.pbf"],
                    'promoteId': 'fadr',
                });

                map.value.addLayer({
                    'id': 'samples-layer',
                    'source': 'samples',
                    'source-layer': 'public.geodata',
                    'type': 'circle',
                    'paint': {
                        'circle-stroke-width': 1,
                        'circle-stroke-color': '#FFFFFF',
                        'circle-color': [
                            'case',
                            ['boolean', ['feature-state', 'beenClicked'], false],
                            '#ffff00',
                            '#1a9641'
                        ],
                        'circle-opacity': 0.8,
                        'circle-radius': 16
                    },
                    filter: ["match", ["get", "internal_id"], props.idlist, true, false]
                });
            });

            const popup = new maplibregl.Popup({
                closeButton: false,
                closeOnClick: false,
            })

            map.value.on('mouseover', 'samples-layer', (e) => {
                // Change the cursor style as a UI indicator.
                map.value.getCanvas().style.cursor = 'pointer';
            });

            map.value.on('mouseleave', 'samples-layer', (e) => {
                map.value.getCanvas().style.cursor = '';
                popup.remove();
            });

            map.value.on('click', 'samples-layer', (e) => {
                // Populate the popup and set its coordinates
                // based on the feature found.
                popup
                    .setLngLat(e.lngLat)
                    .setHTML(JSON.stringify(e.features[0].properties))
                    .addTo(map.value);
                let newFadr = e.features[0].properties["fadr"];

                let newFadrFound = currentFadr["fadr"].indexOf(newFadr)
                if (newFadrFound > -1) {
                    //remove old paint
                    map.value.setFeatureState(
                        {
                            source: 'samples',
                            sourceLayer: 'public.geodata',
                            id: newFadr
                        },
                        { beenClicked: false }
                    );

                    // remove from filters
                    currentFadr["fadr"].splice(newFadrFound, 1)
                } else {
                    // apply new paint
                    map.value.setFeatureState(
                        {
                            source: 'samples',
                            sourceLayer: 'public.geodata',
                            id: newFadr
                        },
                        { beenClicked: true }
                    );

                    // add to filters
                    currentFadr["fadr"].push(newFadr);
                }

                context.emit('mapClick', currentFadr);
            });

        };

        const updateSamplesLayer = () => {
            map.value.removeLayer('samples-layer');

            map.value.addLayer({
                    'id': 'samples-layer',
                    'source': 'samples',
                    'source-layer': 'public.geodata',
                    'type': 'circle',
                    'paint': {
                        'circle-stroke-width': 1,
                        'circle-stroke-color': '#FFFFFF',
                        'circle-color': [
                            'case',
                            ['boolean', ['feature-state', 'beenClicked'], false],
                            '#ffff00',
                            '#1a9641'
                        ],
                        'circle-opacity': 0.8,
                        'circle-radius': 16
                    },
                    filter: ["match", ["get", "internal_id"], props.idlist, true, false]
                });

        };

        onMounted(() => {
            buildMap()
        });

        onUnmounted(() => {
            // TODO: remove even listeners too
            map.value?.remove();
        })


        return {
            map, mapContainer, currentFadr
        }
    }
}

</script>


<style lang="css">
.map-wrap {
    position: relative;
    height: 100vh;
    width: 100%;
}

.map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    /* z-index: -1; */
}
</style>