var VPMap = (function () {
    let vp_template = `
    <template v-if="!config.libur&&!hasPresent&&!(mm().add(2, 'H').unix() < parseInt(config.timeIn)||!config.timeIn||!config.timeOut)">
        <a @click="modal('show');initCamera()" href="javascript:void(0)" class="act-btn">
            <i class="fas fa-qrcode"></i>
        </a>
    </template>

    <div class="container">
        <div class="card">
            <div class="card-body">
                <div style="font-size: 35px;" class="text-center text-bold">{{now.format('HH:mm')}}</div>
                <div class="text-center">{{mm().format('dddd, LL')}}</div>
                <div class="my-4 text-center">
                    <strong v-if="config.libur">Libur : {{config.libur}}</strong>
                </div>
                <template v-if="supported&&!config.libur&&config">
                    <div class="text-center">
                        <div> 
                            <div v-if="config.ptim">Sudah Masuk : <span class="badge bg-success">{{config.ptim.format("HH:mm")}}</span></div>
                            <div v-else-if="config.tim">Jam Masuk Pada: <strong>{{config.tim.format("HH:mm")}}</strong></div>
                            <div v-if="config.ptom">Sudah Keluar : <span class="badge bg-success">{{config.ptom.format("HH:mm")}}</span></div>
                            <div v-else-if="config.tom">Jam Keluar Pada: <strong>{{config.tom.format("HH:mm")}}</strong></div>
                        </div>
                    </div>
                    <template v-if="(mm().add(2, 'H').unix() < parseInt(config.timeIn)||!config.timeIn||!config.timeOut)&&config.timeIn&&config.timeOut">
                        <div class="text-center">
                            <button title="Belum bisa presensi" style="width: 200px;height: 200px;border-radius: 50%;" class="btn btn-secondary btn-lg"> <i style="font-size: 5rem;" class="fas fa-fingerprint fa-5x"></i> </button>
                            <br>
                        </div>
                    </template>
                    <template v-else-if="hasPresent">
                        <div class="text-center">
                            <button style="width: 200px;height: 200px;border-radius: 50%;" class="btn btn-success btn-lg"> <i style="font-size: 5rem;" class="fas fa-fingerprint fa-5x"></i> </button>
                            <br>
                        </div>
                    </template>
                    <template v-else-if="!$store.state.config.is_https||(locationGranted&&myLat&&myLon)">
                        <div class="text-center">
                            <button v-if="distanceToPusat<=config.staff_radius||config.staff_radius==0" :class="serve?'blink_me':''" @click="presentMap" style="width: 200px;height: 200px;border-radius: 50%;" class="btn btn-primary btn-lg"> <i style="font-size: 5rem;" class="fas fa-fingerprint fa-5x"></i> </button>
                            <button v-else-if="distanceToPusat>config.staff_radius" style="width: 200px;height: 200px;border-radius: 50%;" class="btn btn-danger btn-lg"> <i style="font-size: 5rem;" class="fas fa-globe-asia fa-5x"></i> </button>
                        </div>
                        <div class="my-2"></div>
                        <div v-if="distanceToPusat>config.staff_radius&&config.staff_radius>0" class="text-center">
                            <strong>Terlalu Jauh</strong>
                            <div class="text-danger">
                                <i class="fas fa-map-marker-alt"></i>
                                {{distanceToPusat>1000?(distanceToPusat*0.001)+' Km':distanceToPusat+' M'}} dari Titik Presensi
                            </div>
                        </div>
                        </template>
                    <template v-else>
                        <div class="text-center">
                            <button @click="requestPermission" style="width: 200px;height: 200px;border-radius: 50%;" :class="onRequestLocation?'blink_me':''" class="btn btn-danger btn-lg"> <i style="font-size: 5rem;" class="fas fa-street-view fa-5x"></i> </button>
                        </div>
                        <div class="my-2"></div>
                        <div v-if="!onRequestLocation" class="text-center text-danger">
                            <i class="fas fa-map-marker-alt"></i>
                            Tidak Bisa Mendapatkan Lokasi
                        </div>
                    </template>
                </template>
                <div v-if="!supported" class="text-center text-danger">
                    <strong>Perangkat Tidak Mendukung Geolokasi</strong>
                </div>
            </div>
        </div>
    </div>



    <div class="modal fade" ref="modal"  tabindex="-1" aria-hidden="true">
        <div class="modal-dialog modal-fullscreen modal-dialog-centered">
          <div class="modal-content card-style">
            <div class="modal-body p-0">
              <div class="content  h-100">
                <div class="text-center" id="reader"></div>
                <strong v-if="qrErr" class="text-danger">{{qrErr}}</strong>
                <div class="text-center my-5">
                    <button @click="stopCamera();modal('hide')" style="width: 45px;height: 45px;border-radius: 50%;" class="btn btn-danger"> <i class="fas fa-times-circle"></i> </button>
                </div>
              </div>
            </div>
          </div>
        </div>
    </div>

    <rekap ref="rek"></rekap>
    `;
    return {
        name: "presence-map",
        template: vp_template,
        data() {
            return {
                config: {
                    present: {}
                },
                serve: false,
                qrLoading: false,
                qrErr: '',
                qrCode: '',
                locationGranted: false,
                onRequestLocation: false,
                supported: "geolocation" in navigator,
                myLon: null,
                myLat: null,
                now: mm(),
                days: {
                    0: 'Minggu',
                    1: 'Senin',
                    2: 'Selasa',
                    3: 'Rabu',
                    4: 'Kamis',
                    5: 'Jumat',
                    6: 'Sabtu',
                },
            }
        },
        mounted() {
            this.loadConfig();
            if (!this.supported) return;
            setInterval(() => {
                this.now = mm();
            }, 100);
            this.requestPermission();
            this.$refs.modal.addEventListener('hide.bs.modal', (e) => {
                this.stopCamera();
            });
        },
        watch: {
            qrCode(v) {
                this.presentQR()
            }
        },
        methods: {
            onScanSuccess(decodedText, decodedResult) {
                this.qrCode = decodedText;
            },
            onScanFailure(error) {
                this.qrErr = error;
            },
            stopCamera() {
                try {
                    this.scanner.html5QrCode.stop()
                } catch (error) {

                }
            },
            initCamera() {
                if (!this.scanner) {
                    this.scanner = {
                        html5QrCode: new Html5Qrcode("reader"),
                        config: { fps: 10, qrbox: { width: screen.width, height: 250 } },
                    };
                }
                this.scanner.html5QrCode.start({ facingMode: "environment" }, this.scanner.config, this.onScanSuccess);
                document.getElementsByTagName('video').style = "100%";
            },
            requestPermission() {
                this.onRequestLocation = true;
                navigator.geolocation.getCurrentPosition((p) => {
                    this.setCurrentPosition(p);
                    // if (!this.hasPresent) this.startWatch();
                }, this.positionError, {
                    enableHighAccuracy: false,
                    timeout: 15000,
                    maximumAge: 0
                });
            },
            setCurrentPosition(position) {
                this.onRequestLocation = false;
                this.locationGranted = true;
                this.myLat = position.coords.latitude;
                this.myLon = position.coords.longitude;
            },
            startWatch() {
                console.log("Start Watch Location")
                if (!this.geoWatch) {
                    if ("geolocation" in navigator && "watchPosition" in navigator.geolocation) {
                        geoWatch = navigator.geolocation.watchPosition(this.setCurrentPosition, (err) => {
                            this.stopWatch();
                            if (!this.config.present) this.startWatch();
                        }, {
                            enableHighAccuracy: false, timeout: 15000, maximumAge: 0
                        });
                    }
                }
            },
            stopWatch() {
                console.log("Stop Watch Location")
                navigator.geolocation.clearWatch(this.geoWatch);
                this.geoWatch = undefined;
            },
            positionError(error) {
                this.onRequestLocation = false;
                this.locationGranted = false;
                if (this.config.present || !this.$store.state.config.is_https) return;
                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
                }
            },
            loadConfig() {
                axios({
                    method: 'GET',
                    url: window.location.href + '/config',
                }).then((response) => {
                    if (!isObject(response.data)) return Swal.fire('Error', gaem({ response }, response.data), 'error');
                    if (response.data.timeIn && response.data.timeOut) {
                        response.data.tim = mm({ unix: response.data.timeIn });
                        response.data.tom = mm({ unix: response.data.timeOut });
                    }
                    if (response.data.present) {
                        response.data.ptim = response.data.present.timeIn ? mm({ unix: response.data.present.timeIn }) : null;
                        response.data.ptom = response.data.present.timeOut ? mm({ unix: response.data.present.timeOut }) : null;
                    }
                    this.config = response.data;
                }, (error) => {
                    return Swal.fire('Error', gaem(error), 'error');
                }).finally(() => this.serve = false);
            },
            presentMap() {
                if (this.serve) return;
                this.serve = true;
                axios({
                    method: 'POST',
                    data: {
                        [this.$store.state.config.csrf.name]: this.$store.state.config.csrf.value,
                        lat: this.myLat,
                        lon: this.myLon,
                    },
                    url: window.location.href + '/present',
                }).then((response) => {
                    if (!isObject(response.data)) return Swal.fire('Error', gaem({ response }, response.data), 'error');
                    this.loadConfig();
                    this.$refs.rek.initCalendar();
                }, (error) => {
                    return Swal.fire('Error', gaem(error), 'error');
                }).finally(() => this.serve = false);
            },
            presentQR() {
                if (this.qrLoading) return;
                this.qrLoading = true;
                axios({
                    method: 'POST',
                    data: {
                        [this.$store.state.config.csrf.name]: this.$store.state.config.csrf.value,
                        qrCode: this.qrCode,
                    },
                    url: window.location.href + '/presentQR',
                }).then((response) => {
                    this.scanner.html5QrCode.stop()
                    this.loadConfig();
                    this.modal('hide');
                    this.$refs.rek.initCalendar();
                }, (error) => {
                    return Swal.fire('Error', gaem(error), 'error');
                }).finally(() => this.qrLoading = false);
            },
            mm() {
                return mm()
            },
            modal(e = 'show') {
                if (!this.mdlInstance) {
                    this.mdlInstance = new bootstrap.Modal(this.$refs.modal);
                }
                switch (e) {
                    case "hide":
                        this.mdlInstance.hide();
                        break;
                    case "show":
                        this.mdlInstance.show();
                        break;
                    case "toggle":
                        this.mdlInstance.toggle();
                        break;
                    case "dispose":
                        this.mdlInstance.dispose();
                        break;
                }
            },
            mm() {
                return mm();
            }
        },
        computed: {
            hasPresent() {
                if (!this.config.present) return false;
                if (parseInt(this.config.present.status) != 1) return true;
                if ((this.config.timeIn.length < 1 || this.config.timeOut.length < 1) && (!this.config.present.timeIn || !this.config.present.timeOut)) return false;
                if (this.config.present.timeOut) return true;
                if (!this.config.present.timeIn) return false;
                if (this.now.unix() > parseInt(this.config.timeOut)) return false;
                return true;
            },
            distanceToPusat() {
                // Obtain the distance in meters using the haversine formula
                let distanceInMeters = getDistanceBetweenPoints(
                    // LatA
                    this.config.lat,
                    // LongA
                    this.config.lon,
                    // LatB
                    this.myLat,
                    // LongB
                    this.myLon,
                );
                return Math.floor(distanceInMeters);
            }
        }
    }
})();
