<script lang="ts">
// *** Import Svelte core
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
// import 'html5-qrcode';
import {Html5Qrcode, Html5QrcodeScannerState, Html5QrcodeSupportedFormats} from 'html5-qrcode';

// *** Import Aether core variables and functions

// *** Import Aether core components
// import Element_input from './element_input.svelte';
// import ae from '/element_input.svelte';
// import Input_element from '/element_input.svelte';

// *** Import Aether module variables and functions

// *** Import Aether module components

// *** Export/Exposed variables and functions for component
export let start_qr_scanner: boolean = true;
export let show_pause_btn: boolean = false; // pause and resume buttons
export let show_qr_manual_text_entry_option: boolean = false;
export let show_qr_manual_badge_id_entry_option: boolean = false;
export let show_qr_scan_result: boolean = true;

export let qr_fps = 15;
export let qr_viewfinder_width = 275; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.
export let qr_facing_mode = 'environment'; // environment, user, { exact: 'environment'}, { exact: 'user'}

// *** Set initial variables
let scanning_status: string = 'not_started';
let qr_scan_result: null|string = null;
let qr_found_text: null|string = null;
let qr_entered_text: null|string = null;
let qr_entered_badge_id: null|string = null;
let show_qr_manual_entry: null|boolean = null;
let disable_submit_badge_id_btn: boolean = true;

// let max_results: number = 50;

const dispatch = createEventDispatcher();

let html5_qr_code: any|null|string = null;
// let html5_qr_code = new Html5Qrcode(
//     'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
// );

// let qr_scan_cfg = { fps: 10, qrbox: 400 }; // default was 250 and using 300 when 600px
let qr_scan_cfg = { fps: qr_fps, qrbox: qr_viewfinder_width }; // 275 seems good... Need to not let the this be larger than the container which changes based on the width of the screen/window.

// let mounted = false;


onMount(() => {
    console.log('** Element Mounted: ** QR Scanner');

    // NOTE: This can only be done after the page has fully loaded. At least that is what my tests have shown so far. -2022-12-02
    if (start_qr_scanner) {
        handle_start_qr_scanning();
    }

    navigator.mediaDevices.getUserMedia({video: true})
    .then(successCallback, errorCallback);
});


onDestroy(() => {
    console.log('** Element Destroyed: ** QR Scanner');

    qr_scan_result = null;
    qr_found_text = null;

    handle_stop_qr_scanning();
});


var successCallback = function(error: any) {
    console.log('Camera access allowed');

    dispatch('qr_camera', {
        status: 'allowed',
    });
};
var errorCallback = function(error: any) {
    if (error.name == 'NotAllowedError') {
        console.log('Camera access not allowed!');

        dispatch('qr_camera', {
            status: 'denied',
        });
    }
};


// $: if (mounted && start_qr_scanner) {
//     console.log('START QR SCANNING');
//     handle_start_qr_scanning();
// } else if (mounted && !start_qr_scanner) {
//     console.log('STOP QR SCANNING');
//     handle_stop_qr_scanning();
// }


function handle_start_qr_scanning() {
    console.log('*** handle_start_qr_scanning() ***');

    qr_scan_result = null;
    qr_found_text = null;

    if (html5_qr_code) {
        console.log('html5_qr_code object found. Clearing and creating new Html5Qrcode...');
        // html5_qr_code.clear();
        document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');

        html5_qr_code = new Html5Qrcode(
            'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
        );
    } else {
        console.log('html5_qr_code not found. Creating new Html5Qrcode...');
        html5_qr_code = new Html5Qrcode(
            'qr_scanner_viewfinder', { formatsToSupport: [ Html5QrcodeSupportedFormats.QR_CODE ] }
        );
    }

    // if (html5_qr_code.getState() == Html5QrcodeScannerState.NOT_STARTED) {
    //     // console.log('Scanner is not started');
    // } else {
    //     console.log('Scanner is already started');
    //     return;
    // }

    html5_qr_code.start({ facingMode: qr_facing_mode }, qr_scan_cfg, handle_qr_scan_success, handle_qr_scan_error).then((ignore: any) => {
        console.log('Scanning has started');
        scanning_status = 'scanning';
        return true;
    }).catch((err) => {
        console.log('There was an error while trying to start the QR scanner');
        return false;
    });
}


function handle_pause_qr_scanning() {
    if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.SCANNING) {
        console.log('Scanner is not scanning!');
        return;
    }

    html5_qr_code.pause();
    scanning_status = 'paused';
}

function handle_resume_qr_scanning() {
    if (html5_qr_code && html5_qr_code.getState() != Html5QrcodeScannerState.PAUSED) {
        console.log('Scanner is not paused!');
        return;
    }

    document.getElementById('qr_scanner_viewfinder').classList.remove('d_none');
    html5_qr_code.resume();
    scanning_status = 'scanning';
}


function handle_stop_qr_scanning() {
    if (html5_qr_code && html5_qr_code.getState() == Html5QrcodeScannerState.NOT_STARTED) {
        console.log('Scanner is not started');
        return;
    }

    // qr_scan_result = null;
    // qr_found_text = null;

    // html5_qr_code.pause();

    html5_qr_code.stop().then((ignore) => {
        console.log('Scanning has stopped');
        document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
        scanning_status = 'not_started';
    }).then((ignore) => {
        // html5_qr_code = null;
        html5_qr_code.clear();
    }).catch((err) => {
        console.log('There was an error while trying to stop the scanning');
        return false;
    });

    // html5_qr_code = null;
}


// Callback function for QrcodeSuccessCallback (decodedText: string, result: Html5QrcodeResult)
function handle_qr_scan_success(decoded_text, decoded_result) {
    console.log('*** handle_qr_scan_success() ***');

    console.log(`QR scanned = ${decoded_text}`, decoded_result);

    qr_scan_result = decoded_text; // NOTE: decoded_result is not currently used by html5-qrcode
    qr_found_text = decoded_text;

    dispatch('qr_scan_result', {
        result: qr_scan_result, // This text will need to be parsed to get more info.
        text: qr_found_text, // This text will need to be parsed to get more info.
        entry_method: 'QR',
    });

    // handle_pause_qr_scanning();

    handle_stop_qr_scanning();

    // html5_qr_code.stop().then((ignore) => {
    //     console.log('Scanning has stopped');
    //     scanning_status = 'not_started';
    //     document.getElementById('qr_scanner_viewfinder').classList.add('d_none');

    //     qr_scan_result = decoded_text;
    //     qr_found_text = decoded_text;

    //     dispatch('qr_scan_result', {
    //         result: qr_scan_result,
    //         entry_method: 'QR',
    //     });

    //     // qr_scan_result = null;
    //     // qr_found_text = null;
    //     return true;
    // }).catch((err) => {
    //     console.log('There was an error while trying to stop the scanning');
    //     return false;
    // });
}


// Callback function for QrcodeErrorCallback (errorMessage: string, error: Html5QrcodeError)
// NOTE: Most of the time this is normal and not an actual error. It just did not find something to scan.
function handle_qr_scan_error(qr_error_message, qr_code_error) {
    // console.log('*** handle_qr_scan_error() ***');

    if (qr_code_error.type) {
        console.log(`Error scanning code = ${qr_error_message}`, qr_code_error);
        return;
    }
}


$: if ( qr_entered_badge_id && qr_entered_badge_id.length >= 11 && qr_entered_badge_id && qr_entered_badge_id.length <= 14) {
    disable_submit_badge_id_btn = false;
} else {
    disable_submit_badge_id_btn = true;
}


function handle_qr_manual_entry() {
    console.log('*** handle_qr_manual_entry() ***');

    if (qr_entered_text) {
        console.log(`QR entered text = ${qr_entered_text}`);
    } else if (qr_entered_badge_id) {
        console.log(`QR entered badge ID = ${qr_entered_badge_id}`);
        qr_entered_text = `OBJ:ot:event_badge,oi:${qr_entered_badge_id}`;
        console.log(`Parse to proper QR badge ID = ${qr_entered_text}`);
    }

    // html5_qr_code.stop().then((ignore) => {
    //     console.log('Scanning has stopped');
    //     document.getElementById('qr_scanner_viewfinder').classList.add('d_none');
    // }).catch((err) => {
    //     console.log('There was an error while trying to stop the scanning');
    // });

    qr_scan_result = qr_entered_text;

    dispatch('qr_scan_result', {
        result: qr_scan_result,
        entry_method: 'manual',
    });

    qr_scan_result = null;
    qr_entered_text = null;
}
</script>


<section
    class="ae_element qr_scanner border-2 border-slate-500/10 space-y-2 flex flex-col gap-1 justify-center items-center min-w-full max-w-full"
    class:not_started={scanning_status == 'not_started'}
    class:paused={scanning_status == 'paused'}
    class:scanning={scanning_status == 'scanning'}
    >

    <!-- <header>
        <h2>QR Scanner</h2>
    </header> -->

    <!-- <fieldset class=""> -->
        <!-- <legend class="d_none">QR Scanner:</legend> -->

        <div
            class="ae_container qr_scanning_container"
            >
            <div
                class="ae_options m-1"
                >
            {#if scanning_status == 'not_started' }
                    <button on:click={handle_start_qr_scanning} class="btn btn-lg variant-soft-primary btn_start"><span class="fas fa-qrcode mx-1"></span> Start Scanning</button>
                    <span class="loading-text">
                        Scanning stopped
                    </span>
            {:else if scanning_status == 'paused' && show_pause_btn}
                    <button on:click={handle_resume_qr_scanning} class="btn btn-md variant-soft-primary btn_resume"><span class="fas fa-play"></span> Resume</button>
                    <span>Scanning paused</span>
            {:else if scanning_status == 'scanning'}
                    <button on:click={handle_stop_qr_scanning} class="btn btn-md variant-soft-secondary btn_stop">
                        <span class="fas fa-crosshairs fa-spin opacity-50 m-1"></span>
                        <!-- <span class="fas fa-stop-circle m-1"></span> -->
                        Stop
                    </button>
                    {#if show_pause_btn}
                        <button on:click={handle_pause_qr_scanning} class="btn btn-lg variant-soft-secondary btn_pause"><span class="fas fa-pause-circle"></span> Pause</button>
                    {/if}
                    <!-- <span>Scanning for QR code...</span> -->
                    <!-- <div class="modal-loading"> -->
                        <!-- <span class="fas fa-crosshairs fa-spin opacity-50"></span> -->
                        <span class="loading-text">
                            Scanning for QR code...
                        </span>
                    <!-- </div> -->
            {/if}
            </div>

            <div id="qr_scanner_viewfinder" class="qr_scanner_viewfinder grow flex flex-col justify-center items-center" style=""></div> <!-- width: 600px -->
        </div>

        {#if show_qr_manual_text_entry_option}
        <div class="ae_container qr_manual_entry text_entry">
            {#if show_qr_manual_entry}
                <label for="entered_text" class="">Enter text</label>
                <input type="text" name="entered_text" id="entered_text" bind:value="{qr_entered_text}">
                <button on:click={handle_qr_manual_entry} class="btn btn-md variant-soft-warning"><span class="fas fa-paper-plane"></span> Submit Text</button>


                <div class="search_by_text">
                    <input type='text' placeholder="Name or Email" label="Name or Email" value={search_query_str} focus={true} on:oninput={handle_oninput_search_query_str} />
                </div>

            {:else}
                <button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-warning"><span class="fas fa-keyboard"></span> Enter Text</button>
            {/if}
        </div>
        {/if}

        {#if show_qr_manual_badge_id_entry_option}
        <div class="ae_container qr_manual_entry badge_id_entry">
            {#if show_qr_manual_entry}
                <form on:submit|preventDefault={() => handle_qr_manual_entry} class="flex">

                    <!-- <label for="entered_badge_id" class="">Enter badge ID</label>
                    <input type="text" name="entered_badge_id" id="entered_badge_id" bind:value="{qr_entered_badge_id}"> -->

                    <input
                        bind:value="{qr_entered_badge_id}"
                        type="text"
                        name="entered_badge_id"
                        id="entered_badge_id"
                        required
                        placeholder="Enter Badge ID"
                        class="input max-w-52"
                        />

                    <button
                        type="submit"
                        on:click={handle_qr_manual_entry}
                        disabled={disable_submit_badge_id_btn}
                        class="btn btn-md variant-ghost-primary m-1"
                        class:btn_default={disable_submit_badge_id_btn}
                        class:btn_primary={!disable_submit_badge_id_btn}
                        >
                        <span class="fas fa-paper-plane mx-1"></span> Submit Badge ID
                    </button>

                </form>
            {:else}
            <button on:click={() => show_qr_manual_entry=true} class="btn btn-md variant-soft-secondary m-1"><span class="fas fa-keyboard mx-1"></span> Enter Badge ID</button>
            {/if}
        </div>
        {/if}

        {#if show_qr_scan_result && qr_scan_result}
        <div class="ae_container qr_scan_result">
            <span class="label">Raw Result:</span>
            <span id="qr_scan_result_value" class="value">{qr_scan_result}</span>
        </div>
        {/if}
    <!-- </fieldset> -->

</section>


<style>
.not_started {
    background-color: hsla(0, 100%, 75%, 0.3);
    border-color: hsla(0, 100%, 75%, 0.6);
}
.paused {
    background-color: hsla(60, 100%, 75%, 0.3);
    border-color: hsla(60, 100%, 75%, 0.6);
}
.scanning {
    background-color: hsla(120, 100%, 75%, 0.3);
    border-color: hsla(120, 100%, 75%, 0.6);
}


.qr_scanner {
    /* outline: solid thin pink; */

    max-width: 100vw;

    /* overflow-x: scroll; */

    display: flex;
    flex-direction: column;
    /* flex-wrap: wrap; */

    justify-content: flex-start;
    align-items: center; /* center */
    align-content: stretch;
}

.ae_element.qr_scanner div.qr_scanner_viewfinder {
    /* max-width: 100vw; */
    /* contain: content; */
    /* contain: contain; */
}

.qr_scanner .qr_scanner_viewfinder {
    /* outline: dashed medium blue; */
    min-width: 400px;

    width: 100%;
    /* max-width: 100%; */
    max-width: 500px;
    /* max-width: 100vw; */
    /* outline: solid thin red; */

    contain: contain;
    overflow-x: scroll;
}

@media (max-width: 767px) {
    .qr_scanner .qr_scanner_viewfinder {
        /* outline: dashed medium red; */
        min-width: 80vw;
        /* width: 100%; */
        /* max-width: 100%; */
        /* max-width: 450px; */
        max-width: 100vw;

        margin: 0;
        padding: 0;
    }
}
</style>
