var VPMap = (function () {
    return {
        name: "peta",
        props: ['id', 'class', 'radius', 'lat', 'lon', 'zoom', 'pusat'],
        template: `<div :id="id"></div>`,
        data() {
            return {
                marker: null,
                circle: {
                    student: null,
                    staff: null
                },
                myLocation: {
                    lat: null,
                    lon: null,
                    marker: null,
                },
                map: null,
                deflat: -1.669685500986571,
                deflon: 118.43261718750001,
                defzoom: 5,
                czoom: null,
                clat: null,
                clon: null,

            }
        },
        mounted() {
        },
        watch: {
            student_radius(e) {
                if (!this.map) return;
                this.setRadius(this.pusat.lat || this.map.getCenter().lat, this.pusat.lon || this.map.getCenter().lng)
            },
            staff_radius(e) {
                if (!this.map) return;
                this.setRadius(this.pusat.lat || this.map.getCenter().lat, this.pusat.lon || this.map.getCenter().lng)
            },
        },
        methods: {
            init() {
                let lastState = localStorage.getItem('setting_attendance_map_data');
                if (!lastState) lastState = "{}";
                lastState = JSON.parse(lastState);
                this.clon = this.lon || lastState.lon || this.deflon;
                this.clat = this.lat || lastState.lat || this.deflat;
                this.czoom = this.zoom || lastState.zoom || this.defzoom;
                setTimeout(() => {
                    let seal = document.getElementById(this.id);
                    let node = seal.parentElement;
                    seal.remove();
                    node.innerHTML = `<div class="${this.class}" id="${this.id}"></div>`;
                    this.map = L.map(this.id).setView([this.clat, this.clon], this.czoom);
                    L.tileLayer("http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}", {
                        maxZoom: 20,
                        subdomains: ["mt0", "mt1", "mt2", "mt3"],
                        attribution: '&copy; <a href="https://www.google.com/intl/en_id/help/terms_maps/">Google</a>'
                    }).addTo(this.map);
                    if (this.pusat.lat && this.pusat.lon) {
                        this.setPusat(null, this.pusat.lat, this.pusat.lon);
                    }
                    this.map.on('click', this.setPusat);
                    this.map.on('zoomend', this.setState);
                    this.map.on('move', this.setState);
                    L.Control.MyLocation = L.Control.extend({
                        onAdd: (map) => {
                            let btn = L.DomUtil.create('div', 'leaflet-bar ');
                            btn.style.backgroundColor = "white";
                            btn.style.cursor = "pointer";
                            btn.innerHTML = `<a title="Lokasi Saya"><i class="fas fa-map-marker-alt"></i></a>`;

                            L.DomEvent
                                .addListener(btn, 'click', L.DomEvent.stop)
                                .addListener(btn, 'click', this.showMyLocation)
                            L.DomEvent.disableClickPropagation(btn);
                            return btn;
                        }
                    })
                    L.control.myLocation = function (opt) {
                        return new L.Control.MyLocation(opt);
                    }
                    L.control.myLocation({ position: 'topleft' }).addTo(this.map);
                    L.Control.AttendanceLocation = L.Control.extend({
                        onAdd: (map) => {
                            let btn = L.DomUtil.create('div', 'leaflet-bar ');
                            btn.style.backgroundColor = "white";
                            btn.style.cursor = "pointer";
                            btn.innerHTML = `<a title="Lokasi Pusat"><i class="fas fa-school"></i></a>`;

                            L.DomEvent
                                .addListener(btn, 'click', L.DomEvent.stop)
                                .addListener(btn, 'click', () => {
                                    if (this.pusat.lat && this.pusat.lon) this.map.setView([this.pusat.lat, this.pusat.lon], 18);;
                                })
                            L.DomEvent.disableClickPropagation(btn);
                            return btn;
                        }
                    })
                    L.control.attendanceLocation = function (opt) {
                        return new L.Control.AttendanceLocation(opt);
                    }
                    L.control.attendanceLocation({ position: 'topleft' }).addTo(this.map);
                    L.Control.ReloadMap = L.Control.extend({
                        onAdd: (map) => {
                            let btn = L.DomUtil.create('div', 'leaflet-bar ');
                            btn.style.backgroundColor = "white";
                            btn.style.cursor = "pointer";
                            btn.innerHTML = `<a title="Refresh"><i class="fas fa-sync"></i></a>`;

                            L.DomEvent
                                .addListener(btn, 'click', L.DomEvent.stop)
                                .addListener(btn, 'click', () => this.init())
                            L.DomEvent.disableClickPropagation(btn);
                            return btn;
                        }
                    })
                    L.control.reloadMap = function (opt) {
                        return new L.Control.ReloadMap(opt);
                    }
                    L.control.reloadMap({ position: 'topleft' }).addTo(this.map);
                }, 154)
            },
            setState(e) {
                localStorage.setItem('setting_attendance_map_data', JSON.stringify({ zoom: this.map.getZoom(), lat: this.map.getCenter().lat, lon: this.map.getCenter().lng }));
            },
            setPusat(e = null, lat = null, lon = null) {
                if (this.marker) this.map.removeLayer(this.marker);
                if (e == null) e = { latlng: { lat, lon } }
                lat = e.latlng.lat || lat;
                lon = e.latlng.lng || lon;
                if (lat && lon) {
                    this.marker = L.marker([lat, lon], { draggable: 'true' });
                    this.marker.on('dragend', (event) => {
                        let marker = event.target;
                        let position = marker.getLatLng();
                        marker.setLatLng(new L.LatLng(position.lat, position.lng), { draggable: 'true' });
                        this.$emit('pusatChange', { lat: position.lat, lon: position.lng });
                        this.setRadius(position.lat, position.lng);
                        this.map.panTo(new L.LatLng(position.lat, position.lng))
                    });
                    if (this.map) this.map.addLayer(this.marker);
                    this.marker.bindPopup(L.popup().setContent("Titik Pusat Presensi"));
                }
                this.$emit('pusatChange', { lat, lon });
                this.setRadius(lat, lon);
            },
            setRadius(lat, lon) {
                if (this.circle.student) this.map.removeLayer(this.circle.student)
                if (this.circle.staff) this.map.removeLayer(this.circle.staff)
                if (!lat || !lon) return;
                if (!this.map) return setTimeout(() => this.setRadius(lat, lon), 50);
                this.circle.student = this.radius.student < 1 ? null : L.circle([lat, lon], {
                    color: 'blue',
                    fillColor: '#f03',
                    fillOpacity: 0.5,
                    radius: this.radius.student
                }).addTo(this.map);
                this.circle.staff = this.radius.staff < 1 ? null : L.circle([lat, lon], {
                    color: 'green',
                    fillColor: '#99cccc',
                    fillOpacity: 0.5,
                    radius: this.radius.staff
                }).addTo(this.map);
            },
            showMyLocation() {
                if (!("geolocation" in navigator)) return Swal.fire("Error", 'Perangkat Tidak Mendukung Geo Lokasi', 'error');
                navigator.geolocation.getCurrentPosition(this.myLocationMarker, this.positionError, {
                    enableHighAccuracy: false,
                    timeout: 15000,
                    maximumAge: 0
                });
            },
            myLocationMarker(position) {
                if (this.myLocation.marker) this.map.removeLayer(this.myLocation.marker);
                this.myLocation.lat = position.coords.latitude;
                this.myLocation.lon = position.coords.longitude;
                this.myLocation.marker = L.marker([position.coords.latitude, position.coords.longitude], {
                    icon: L.icon({
                        iconUrl: this.$store.state.config.base_url + '/panel/assets/img/marker-icon.png',
                        iconSize: [25, 41],
                        iconAnchor: [12, 43], // point of the icon which will correspond to marker's location
                    })
                }).addTo(this.map);
                this.myLocation.marker.bindPopup(L.popup().setContent("Lokasi Saya"));
                if (!this.marker) return this.map.setView([this.myLocation.lat, this.myLocation.lon], 18);;
                let southWest = L.latLng(this.pusat.lat, this.pusat.lon), northEast = L.latLng(position.coords.latitude, position.coords.longitude);
                let bounds = L.latLngBounds(southWest, northEast);
                this.map.fitBounds(bounds, { padding: [50, 50] });
            },
            positionError(error) {
                switch (error.code) {
                    case error.PERMISSION_DENIED:

                        Swal.fire("Error", 'Izin Lokasi Tidak Didapatkan', 'error');
                        break;

                    case error.POSITION_UNAVAILABLE:

                        Swal.fire("Error", 'Lokasi Tidak Tersedia', 'error');
                        break;

                    case error.TIMEOUT:

                        Swal.fire("Error", 'Waktu Habis, Silahkan Coba Lagi', 'error');
                        break;

                    case error.UNKNOWN_ERROR:

                        Swal.fire("Error", 'Kesalahan Tidak Diketahui', 'error');
                        break;
                    default:
                        Swal.fire("Error", 'Kesalahan Tidak Diketahui', 'error');
                        break
                }
            },
            modal(e = 'show') {
                if (!this.mdl) {
                    this.mdl = new bootstrap.Modal(this.$refs.modal);
                }
                switch (e) {
                    case "hide":
                        this.mdl.hide();
                        break;
                    case "show":
                        this.mdl.show();
                        break;
                    case "toggle":
                        this.mdl.toggle();
                        break;
                    case "dispose":
                        this.mdl.instance.dispose();
                        break;
                }
            }
        },
        computed: {
            student_radius() {
                return this.radius.student;
            },
            staff_radius() {
                return this.radius.staff;
            }
        }
    }
})();
