<template>
    <v-dialog v-model="props.dialog" transition="dialog-bottom-transition" width="700" max-width="700" persistent
        @after-enter="handleScanVisitorQRCode">
        <v-container class="d-flex justify-center" max-height="90vh">
            <!-- QR code reader container -->
            <v-card elevation="2" class="d-flex flex-column align-center pa-2 w-100 h-100">
                <v-toolbar>
                    <v-card-title class="text-h5"> Scan QR Code </v-card-title>
                    <v-spacer />
                    <v-btn color="grey-darken-1" icon="mdi-close" @click="closeDialog()" />
                </v-toolbar>

                <div id="reader" class="d-flex justify-center align-center w-100 h-100"
                    style="height: calc(100vh - 64px)">
                    <!-- The QR code scanner box -->
                    <!-- This is where the QR code scanner will be displayed -->
                </div>
                <!-- Show Error Messages -->
                <div v-if="showNotFoundMessage" class="text-error mt-8">
                    <p>{{ errorMessage }}</p>
                </div>
                <!-- Switch camera button inside the reader box -->
                <v-btn color="primary" icon class="mt-4" @click="switchCamera()">
                    <v-icon icon="mdi-camera-switch" large />
                </v-btn>
            </v-card>
        </v-container>
    </v-dialog>
    <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
</template>
<script setup lang="ts">
const { $Html5Qrcode }: any = useNuxtApp();

const props = defineProps({
    dialog: {
        type: Boolean,
        default: false,
    },
});

const scannedValue = defineModel<string>("scannedValue", {
    default: "",
});

const emit = defineEmits(["closeDialog"]);

const message = ref("");
const messageColor = ref("");
const messageSnackbar = ref(false);

function showMessage(msg: string, color: string) {
    message.value = msg;
    messageColor.value = color;
    messageSnackbar.value = true;
}

const html5QrCodeInstance = ref<any>(null);
const cameraFacingMode = ref<string>("environment");

const showNotFoundMessage = ref<boolean>(false);
const errorMessage = ref<string>("");

const handleScanVisitorQRCode = async () => {
    if (html5QrCodeInstance.value) return;
    const config = { fps: 10, qrbox: { width: 250, height: 250 } };
    html5QrCodeInstance.value = new $Html5Qrcode("reader");
    html5QrCodeInstance.value
        .start(
            { facingMode: cameraFacingMode.value },
            config,
            async (qrCodeMessage: string) => {
                showNotFoundMessage.value = false;
                scannedValue.value = qrCodeMessage;
                console.log(`QR Code scanned: ${qrCodeMessage}`);
                setTimeout(() => {
                    closeDialog();
                }, 100);
            },
            (msg: string) => {
                if (msg === "QR Code no longer in front") {
                    showNotFoundMessage.value = true;
                    errorMessage.value = msg;
                    showMessage(msg, "error");
                }
            }
        )
        .catch((err: any) => {
            showMessage(`Unable to start scanning, error: ${err}`, "error");
        });
};

const isValidUrl = (string: string) => {
    try {
        new URL(string);
        return true;
    } catch (_) {
        return false;
    }
};

const switchCamera = async () => {
    await stopScanner();
    cameraFacingMode.value =
        cameraFacingMode.value === "environment" ? "user" : "environment";
    showMessage(
        `Switched to ${cameraFacingMode.value === "environment" ? "Back" : "Front"
        } Camera`,
        "info"
    );
    handleScanVisitorQRCode();
};

const closeDialog = () => {
    emit("closeDialog");
    stopScanner();
};

const stopScanner = () => {
    return new Promise<void>((resolve, reject) => {
        if (html5QrCodeInstance.value) {
            html5QrCodeInstance.value
                .stop()
                .then(() => {
                    html5QrCodeInstance.value.clear();
                    html5QrCodeInstance.value = null;
                    showNotFoundMessage.value = false;
                    resolve(); // Resolve the promise when the scanner is fully stopped
                })
                .catch((err: any) => {
                    showMessage("Unable to stop scanning.", err);
                    reject(err); // Reject the promise if there's an error
                });
        } else {
            resolve(); // Resolve immediately if no scanner instance exists
        }
    });
};
</script>
