import ApplicationController from "./application_controller";
import L            from 'leaflet';

export default class extends ApplicationController {

    /**
     *
     * @type {string[]}
     */
    static targets = [
        "search",
        "lat",
        "lng"
    ];

    /**
     *
     */
    connect() {
        const default_lat = this.latTarget.value;
        const default_lng = this.lngTarget.value;
        const default_zoom = this.data.get('zoom');
        const max_zoom = '18';

        let base64icon = 'data:image/png;base64,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';
        let base64shadow = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAYAAACoYAD2AAAC5ElEQVRYw+2YW4/TMBCF45S0S1luXZCABy5CgLQgwf//S4BYBLTdJLax0fFqmB07nnQfEGqkIydpVH85M+NLjPe++dcPc4Q8Qh4hj5D/AaQJx6H/4TMwB0PeBNwU7EGQAmAtsNfAzoZkgIa0ZgLMa4Aj6CxIAsjhjOCoL5z7Glg1JAOkaicgvQBXuncwJAWjksLtBTWZe04CnYRktUGdilALppZBOgHGZcBzL6OClABvMSVIzyBjazOgrvACf1ydC5mguqAVg6RhdkSWQFj2uxfaq/BrIZOLEWgZdALIDvcMcZLD8ZbLC9de4yR1sYMi4G20S4Q/PWeJYxTOZn5zJXANZHIxAd4JWhPIloTJZhzMQduM89WQ3MUVAE/RnhAXpTycqys3NZALOBbB7kFrgLesQl2h45Fcj8L1tTSohUwuxhy8H/Qg6K7gIs+3kkaigQCOcyEXCHN07wyQazhrmIulvKMQAwMcmLNqyCVyMAI+BuxSMeTk3OPikLY2J1uE+VHQk6ANrhds+tNARqBeaGc72cK550FP4WhXmFmcMGhTwAR1ifOe3EvPqIegFmF+C8gVy0OfAaWQPMR7gF1OQKqGoBjq90HPMP01BUjPOqGFksC4emE48tWQAH0YmvOgF3DST6xieJgHAWxPAHMuNhrImIdvoNOKNWIOcE+UXE0pYAnkX6uhWsgVXDxHdTfCmrEEmMB2zMFimLVOtiiajxiGWrbU52EeCdyOwPEQD8LqyPH9Ti2kgYMf4OhSKB7qYILbBv3CuVTJ11Y80oaseiMWOONc/Y7kJYe0xL2f0BaiFTxknHO5HaMGMublKwxFGzYdWsBF174H/QDknhTHmHHN39iWFnkZx8lPyM8WHfYELmlLKtgWNmFNzQcC1b47gJ4hL19i7o65dhH0Negbca8vONZoP7doIeOC9zXm8RjuL0Gf4d4OYaU5ljo3GYiqzrWQHfJxA6ALhDpVKv9qYeZA8eM3EhfPSCmpuD0AAAAASUVORK5CYII=';
        let markerIcon = L.icon({
            iconUrl: base64icon,
            iconAnchor: [12, 41],
            iconSize: [25, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41],
            shadowUrl: base64shadow
        });

        this.leafletMap = L.map(this.data.get('id'), {
            center: [default_lat, default_lng],
            zoom: default_zoom
        });

        this.leafLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
            maxZoom: max_zoom
        }).addTo(this.leafletMap);

        this.leafletMarker = L.marker([default_lat, default_lng], {
            icon: markerIcon,
            draggable: true,
            autoPan:true,
            autoPanPadding:L.point(100, 100)
        }).addTo(this.leafletMap);

        this.leafletMarker.on('dragend', () => {
            this.updateCoords();
        });

        this.leafletMap.on('click', (e) => {
            this.leafletMarker.setLatLng(e.latlng);
            this.updateCoords();
            this.leafletMap.panTo(e.latlng);
        });

        /**
         * @see https://stackoverflow.com/questions/36246815/data-toggle-tab-does-not-download-leaflet-map/36257493#36257493
         */
        let tabEl = document.querySelector('a[data-bs-toggle="tab"]')
        if(tabEl !== null){
            tabEl.addEventListener('shown.bs.tab',  () => this.leafletMap.invalidateSize())
        }
    }

    /**
     *
     */
    updateCoords() {
        this.latTarget.value = this.leafletMarker.getLatLng().lat;
        this.lngTarget.value  = this.leafletMarker.getLatLng().lng;

        this.latTarget.dispatchEvent(new Event('change'));
        this.lngTarget.dispatchEvent(new Event('change'));
    }

    /**
     *
     */
    search() {
        const results = this.element.querySelector('.marker-results');

        if (this.searchTarget.value.length <= 3) {
            return;
        }

        axios
            .get('https://nominatim.openstreetmap.org/search?format=json&limit=5&q=' + this.searchTarget.value)
            .then(response => {

                let items = [];

                response.data.forEach((val) => {
                    let bb = val.boundingbox;
                    let lat = val.lat;
                    let lng = val.lon;
                    let name = val.display_name;
                    items.push("<li style='cursor:pointer' data-name='" + name + "' data-lat='" + lat + "' data-lng='" + lng + "' data-lat1='" + bb[0] + "' data-lat2='" + bb[1] + "' data-lng1='" + bb[2] + "' data-lng2='" + bb[3] + "' data-type='" + val.osm_type + "' data-action='click->map#chooseAddr'>" + val.display_name + "</li>");
                });

                results.innerHTML = null;

                if (items.length !== 0) {
                    results.innerHTML = "<ul class='my-2'>"+items.join('')+"</ul>";
                    return;
                }

                results.innerHTML = "<small>No results found</small>";
            });

    }

    /**
     *
     * @param e
     */
    chooseAddr(e) {

        const name = e.target.getAttribute("data-name");
        const lat = e.target.getAttribute("data-lat"); //for centering marker
        const lng = e.target.getAttribute("data-lng"); //for centering marker
        const lat1 = e.target.getAttribute("data-lat1");
        const lat2 = e.target.getAttribute("data-lat2");
        const lng1 = e.target.getAttribute("data-lng1");
        const lng2 = e.target.getAttribute("data-lng2");
        const loc1 = new L.LatLng(lat1, lng1);
        const loc2 = new L.LatLng(lat2, lng2);
        const bounds = new L.LatLngBounds(loc1, loc2);

        this.leafletMap.fitBounds(bounds);
        this.leafletMarker.setLatLng([lat, lng]);
        this.updateCoords();
        this.searchTarget.value = name;
    }

}
