<script lang="ts">
    // *** Import Svelte specific
    import { onDestroy, onMount, tick } from 'svelte';
    import { afterNavigate } from '$app/navigation';

    // *** Import other supporting libraries
    // import { liveQuery } from "dexie";
    import {
        ShieldEllipsis,
        ShieldMinus,
        ShieldPlus,
        ShieldUser,
        User,
        UserCheck
    } from '@lucide/svelte';

    // *** Import Aether specific variables and functions
    import { ae_util } from '$lib/ae_utils/ae_utils';
    import { ae_loc, ae_sess, ae_api, slct, slct_trigger } from '$lib/stores/ae_stores';
    // import { core_func } from '$lib/ae_core/ae_core_functions';
    // Ideally the Event related stores should not be imported here?
    import { events_loc } from '$lib/stores/ae_events_stores';
    // import { db_events } from "$lib/db_events";

    // export let hidden: boolean = false;

    // *** Setup Svelte properties
    interface Props {
        log_lvl?: number;
        hide?: null | boolean;
        focus_input: boolean;
        expand?: boolean;
        show_passcode_input: boolean;
        trigger_clear_access: null | boolean;
    }

    let {
        log_lvl = $bindable(0),
        hide = $bindable(false),
        focus_input = $bindable(false),
        expand = $bindable(false),
        show_passcode_input = $bindable(false),
        trigger_clear_access = $bindable(null)
    }: Props = $props();

    let entered_passcode: null | string = $state(null);
    let checked_passcode: null | string = $state(null);
    // let password_checked: boolean = $state(false);
    // let entered_passcode: null|string = '';
    // let show_passcode_input: boolean = $state(false);
    // let show_passcode_input: boolean = false;

    // let trigger: null|string|boolean = null;
    let trigger: null | string | boolean = $state(null);

    // const dispatch = createEventDispatcher();

    // WARNING: There is a bug (I think) around here related to the entered_passcode not being cleared. There seems to be something different about how Svelte handles state in this component compared to the others. This might be related to the `$effect` or `$derived` usage. Maybe there are conflicting things trying to update the $ae_loc store at the same time.
    onMount(() => {
        // log_lvl = 2;
        if (log_lvl > 1) {
            console.log('** Element Mounted: ** Element Access Type');
        }
        entered_passcode = '';
        trigger = null;

        // /** @type {HTMLElement | null} */
        // const to_focus = document.getElementById('access_passcode_input');
        // to_focus?.focus();
    });

    onDestroy(() => {
        if (log_lvl > 1) {
            console.log('** Element Destroyed: ** Element Access Type');
        }

        // Clean up any references or listeners if needed
        entered_passcode = null; // Clear the entered passcode
        show_passcode_input = false;

        // Reset trigger
        trigger = null;
    });

    // afterNavigate(() => {
    // 	/** @type {HTMLElement | null} */
    // 	const to_focus = document.getElementById('access_passcode_input');
    // 	to_focus?.focus();
    // });

    $effect(() => {
        if (
            entered_passcode &&
            entered_passcode.length >= 5 &&
            entered_passcode != checked_passcode
        ) {
            checked_passcode = entered_passcode;
            if (log_lvl) {
                console.log(`entered_passcode=${entered_passcode}`);
            }
            handle_check_access_type_passcode();
        }
    });

    $effect(() => {
        if (trigger && $ae_loc.access_type) {
            trigger = false;
            if (log_lvl) {
                console.log(`$ae_loc.access_type=${$ae_loc.access_type}`);
            }

            let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type);

            $ae_loc = { ...$ae_loc, ...access_checks_results };
            $ae_loc = $ae_loc;
            $ae_loc.sys_menu.expand = false;
        } else if (trigger) {
            trigger = false;
            if (log_lvl) {
                console.log(`$ae_loc.access_type=not set`);
            }

            // Send an empty string to reset the permissions. This is the same as sending 'anonymous'.
            let access_checks_results = ae_util.process_permission_checks('');

            $ae_loc = { ...$ae_loc, ...access_checks_results };
            $ae_loc = $ae_loc;
        }
    });

    // This does not seem to work. I feel like it should though...?
    $effect(() => {
        if (!hide && focus_input) {
            focus_input = false;
            // log_lvl = 2;
            // await tick();
            // document.getElementById('access_passcode_input')?.focus();
            if (log_lvl > 1) {
                console.log('Effect: Setting focus on the passcode input field');
            }
            /** @type {HTMLElement | null} */
            const to_focus = document.getElementById('access_passcode_input');
            to_focus?.focus();
        }
    });

    $effect(() => {
        if (trigger_clear_access) {
            trigger_clear_access = false;
            if (log_lvl) {
                console.log(`trigger_clear_access=${trigger_clear_access}`);
            }
            handle_clear_access();
        }
    });

    function handle_check_access_type_passcode() {
        if (log_lvl > 1) {
            console.log(
                `*** handle_check_access_type_passcode() *** passcode list:`,
                $ae_loc.site_access_code_kv
            );
        }

        // Reminder: super > manager > administrator > trusted > public > authenticated > anonymous

        if (entered_passcode && entered_passcode.length >= 5) {
            if (
                $ae_loc.site_access_code_kv.super.length >= 8 &&
                $ae_loc.site_access_code_kv.super == entered_passcode
            ) {
                console.log('Super passcode matched');

                window.localStorage.setItem('access_type', 'super');

                $ae_loc.access_type = 'super';
            } else if (
                $ae_loc.site_access_code_kv.manager.length >= 5 &&
                $ae_loc.site_access_code_kv.manager == entered_passcode
            ) {
                console.log('Manager passcode matched');

                window.localStorage.setItem('access_type', 'manager');

                $ae_loc.access_type = 'manager';
            } else if (
                $ae_loc.site_access_code_kv.administrator.length >= 5 &&
                $ae_loc.site_access_code_kv.administrator == entered_passcode
            ) {
                console.log('Administrator passcode matched');

                window.localStorage.setItem('access_type', 'administrator');

                $ae_loc.access_type = 'administrator';
            } else if (
                $ae_loc.site_access_code_kv.trusted.length >= 5 &&
                $ae_loc.site_access_code_kv.trusted == entered_passcode
            ) {
                console.log('Trusted passcode matched');

                window.localStorage.setItem('access_type', 'trusted');

                $ae_loc.access_type = 'trusted';
            } else if (
                $ae_loc.site_access_code_kv.public.length >= 5 &&
                $ae_loc.site_access_code_kv.public == entered_passcode
            ) {
                console.log('Public passcode matched');

                window.localStorage.setItem('access_type', 'public');

                $ae_loc.access_type = 'public';
            } else if ($ae_loc.site_access_code_kv.authenticated == entered_passcode) {
                console.log('Authenticated passcode matched');

                window.localStorage.setItem('access_type', 'authenticated');

                $ae_loc.access_type = 'authenticated';
            } else {
                if (log_lvl > 1) {
                    console.log('Entered passcode does not match any of the site access codes.');
                }

                if ($ae_loc.access_type != 'anonymous') {
                    console.log('Access type is not anonymous');
                }
                // window.localStorage.setItem('access_type', 'anonymous');

                // $ae_loc.access_type = 'anonymous';

                // trigger = 'process_permission_check';

                // $ae_loc = $ae_loc; // Trigger Svelte just in case
                // ae_loc.set($ae_loc);
                // console.log($ae_loc);

                // dispatch_access_type_changed();

                return false;
            }

            entered_passcode = '';
            trigger = 'process_permission_check';

            $ae_loc.app_cfg.show_element__menu = false;
            $ae_loc.app_cfg.show_element__menu_btn = true;

            // WARNING 2024-08-21: For some reason the config element does not auto show or hide when the access type changes.
            if (!$ae_loc.iframe && $ae_loc.authenticated_access) {
                $ae_loc.app_cfg.show_element__access_type = true;
                $ae_loc.app_cfg.show_element__cfg = true;
            } else if ($ae_loc.iframe && $ae_loc.trusted_access) {
                $ae_loc.app_cfg.show_element__access_type = true;
                $ae_loc.app_cfg.show_element__cfg = true;
            } else {
                $ae_loc.app_cfg.show_element__access_type = true;
                $ae_loc.app_cfg.show_element__cfg = false;
            }

            // dispatch_access_type_changed();

            return true;
        } else {
            if (log_lvl > 1) {
                console.log('Entered passcode too short.');
            }

            // $ae_loc.access_type = null; // 'anonymous';

            // dispatch_access_type_changed()

            return null;
        }
    }

    function handle_clear_access() {
        // console.log('handle_clear_access()');
        // NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
        window.localStorage.setItem('access_type', 'anonymous');

        // $ae_loc.access_type = null; // 'anonymous';
        // Revert back to the user's access type after quick access (temporarily escalate permissions) is turned off.
        $ae_loc.access_type = $ae_loc.user_access_type ?? 'anonymous';
        trigger = 'process_permission_check';

        entered_passcode = ''; // Clear the entered passcode
        // Reset so the same passcode can be re-entered after clearing.
        // Without this, the $effect guard (entered_passcode != checked_passcode) silently
        // blocks re-entry of the same passcode until the component remounts (page refresh).
        checked_passcode = null;
        show_passcode_input = true;

        $ae_loc.app_cfg.show_element__menu = false;
        $ae_loc.app_cfg.show_element__menu_btn = true;

        $ae_loc.edit_mode = false;

        return true;
    }
</script>

<section
    id="AE-Quick-Access-Type"
    class="
        ae_access_type
        hidden-print

        bg-blue-100 text-gray-900
        dark:bg-blue-800 dark:text-gray-200

        flex flex-col flex-wrap gap-1
        items-end justify-center

        w-full
        p-1
        border-2 border-gray-200

        duration-300 delay-150 hover:delay-1000 hover:ease-out
        transition-all
        "
    class:hidden={hide}
>
    <!-- class:hidden={!$ae_sess.show__sign_in_out__fields} -->
    <header class="ae_header hidden">
        <h2 class="text-sm text-center font-semibold">Passcode Sign In</h2>
    </header>

    <!-- Show list of authorized sessions and presentations for a user -->
    <!-- {#if $ae_loc.access_type == 'administrator'}
        {#if $events_loc.auth__kv.session}
        Sessions:
        <ul>
        {#each Object.entries($events_loc.auth__kv.session) as [key, value] (key)}
        <li><a href="/events/{event_id}/session/{key}">
            {key}
            </a></li>
        {/each}
        </ul>
        {/if}
    {/if} -->

    <div class="transition-all">
        {#if $ae_loc.trusted_access && $ae_loc.edit_mode}
            {#if $ae_loc.manager_access}
                {#if $ae_loc?.sync_local_config}
                    <button
                        type="button"
                        onclick={() => {
                            $ae_loc.sync_local_config = false;
                            $events_loc.pres_mgmt.sync_local_config = false;

                            $ae_loc.lock_config = false;
                            $events_loc.pres_mgmt.lock_config = false;

                            // dispatch_sync_local_config_changed();
                            // tick();
                            return false;
                        }}
                        class="btn btn-sm preset-tonal-success border border-success-500 hover:preset-filled-success-500 transition-all hover:transition-all *:hover:inline"
                        title="Syncing the local configuration with the remote configuration."
                    >
                        <span class="fas fa-sync m-1"></span>
                        <span class="hidden"> Sync </span>
                    </button>
                {:else}
                    <button
                        type="button"
                        onclick={() => {
                            $ae_loc.sync_local_config = true;
                            $events_loc.pres_mgmt.sync_local_config = true;

                            $ae_loc.lock_config = true;
                            $events_loc.pres_mgmt.lock_config = true;

                            // dispatch_sync_local_config_changed();
                            // tick();
                            return true;
                        }}
                        class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 transition-all hover:transition-all *:hover:inline"
                        title="Currently not syncing with the remote server. Re-sync the local configuration with the remote configuration?"
                    >
                        <span class="fas fa-unlink m-1"></span>
                        <span class="hidden"> Re-sync? </span>
                    </button>
                {/if}
            {/if}

            <!-- {#if $ae_loc.edit_mode}
            <button
                type="button"
                onclick={() => {
                    $ae_loc.edit_mode = false;
                    // dispatch_edit_mode_changed();
                }}
                class="btn btn-sm px-2 variant-ghost-success hover:variant-filled-success transition-all"
                title="Edit mode is currently enabled. Click to disable."
                >
                <span class="fas fa-toggle-on mx-1"></span>
                Edit Mode On
            </button>
        {:else}
            <button
                type="button"
                onclick={() => {
                    $ae_loc.edit_mode = true;
                    // dispatch_edit_mode_changed();
                }}
                class="btn btn-sm px-2 variant-ghost-warning hover:variant-filled-warning transition-all space-x-1 *:hover:inline"
                title="Edit mode is currently disabled. Click to enable."
                >
                <span class="fas fa-toggle-off mx-1"></span>
                Edit
                <span class="hidden">
                    Mode?
                </span>
            </button>
        {/if} -->
        {/if}
    </div>

    <div class="flex flex-row flex-wrap gap-1 items-end justify-end w-full transition-all">
        {#if $ae_loc?.access_type && $ae_loc?.access_type == 'anonymous'}
            <span>
                <button
                    type="button"
                    onclick={() => {
                        // handle_check_access_type_passcode();
                        trigger = true;
                    }}
                    class="btn btn-sm preset-tonal-success hover:preset-filled-warning-500 access_type_unlock_btn transition-all"
                    title="Anonymous public access is currently set. Access mode is disabled/locked."
                >
                    <span class="fas fa-lock mx-1"></span>
                    <span class="lock_icon">Locked</span>

                    <span class="fas fa-unlock mx-1 unlock_icon hidden"></span>
                    {#if show_passcode_input}
                        <span class="unlock_text">Cancel</span>
                    {:else}
                        <span class="unlock_text">Access?</span>
                    {/if}
                </button>
            </span>
        {/if}

        {#if $ae_loc?.access_type && $ae_loc?.access_type != 'anonymous'}
            <span class="flex flex-row gap-1 items-center justify-center">
                <!-- <span class="fas fa-unlock mx-1"></span> -->
                <ShieldPlus class="inline-block" />

                <span
                    class="*:hover:inline"
                    title={`Current access type/level: ${$ae_loc.access_type}`}
                >
                    {#if $ae_loc.access_type == 'super'}
                        <span class="fas fa-hat-wizard m-1"></span>
                        <span class="hidden">Super</span>
                    {:else if $ae_loc.access_type == 'manager'}
                        <span class="fas fa-user-shield m-1"></span>
                        <span class="hidden">Manager</span>
                    {:else if $ae_loc.access_type == 'administrator'}
                        <span class="fas fa-user-ninja m-1"></span>
                        <span class="hidden">Administrator</span>
                    {:else if $ae_loc.access_type == 'trusted'}
                        <span class="fas fa-user-check m-1"></span>
                        <span class="hidden">Trusted Access</span>
                    {:else if $ae_loc.access_type == 'public'}
                        Public
                        <span class="hidden">Access</span>
                    {:else if $ae_loc.access_type == 'authenticated'}
                        Authenticated
                        <span class="hidden">Access</span>
                    {:else if $ae_loc.access_type == 'anonymous'}
                        Anonymous Access
                    {:else}
                        Unknown Access
                    {/if}
                </span>

                {#if $ae_loc?.user_access_type && $ae_loc?.access_type == $ae_loc?.user_access_type && !show_passcode_input}
                    <button
                        type="button"
                        onclick={() => {
                            // handle_clear_access();
                            // trigger_clear_access = true;
                            show_passcode_input = true;
                        }}
                        class="btn btn-sm variant-outline-surface hover:preset-tonal-warning border border-warning-500 transition-all"
                        title={`Current user access level: "${$ae_loc.user_access_type}". Click use passcode for a different access level.`}
                    >
                        <!-- <span class="fas fa-lock mx-1"></span> -->
                        <!-- <ShieldMinus /> -->
                        <ShieldEllipsis class="inline-block" />
                        Passcode?
                    </button>
                {:else if !show_passcode_input}
                    <button
                        type="button"
                        onclick={() => {
                            // handle_clear_access();
                            trigger_clear_access = true;
                            show_passcode_input = true;
                            // show_passcode_input = true;
                        }}
                        class="btn btn-sm variant-outline-warning hover:preset-tonal-warning border border-warning-500 transition-all"
                        title={`Current access level: "${$ae_loc.access_type}". Click to clear the temporary access level.`}
                    >
                        <!-- <span class="fas fa-lock mx-1"></span> -->
                        <ShieldMinus class="inline-block" />
                        Clear?
                    </button>
                {/if}
            </span>
        {/if}

        {#if show_passcode_input}
            <span class="flex flex-row gap-1 items-center justify-between w-full">
                <span>
                    <ShieldEllipsis class="inline-block text-gray-500" />
                    <span class="unlock_text text-sm">Passcode:</span>
                </span>

                <!-- svelte-ignore a11y_autofocus -->
                <input
                    id="access_passcode_input"
                    bind:value={entered_passcode}
                    class="input w-32 transition-all"
                    class:hidden={!show_passcode_input}
                    type="text"
                    placeholder="Passcode"
                    autofocus={show_passcode_input}
                />
                <!-- <div class="current_text transition-all">{$ae_loc.access_type}</div> -->
            </span>
        {/if}
    </div>
</section>

<style lang="scss">
    /* BEGIN: AE's Svelte Quick Access Type component  */
    /*
#xxx-AE-Quick-Access-Type {
    // position: absolute;
    position: fixed;
    // position: relative;
    // position: static;
    // position: sticky;
    // top: 1em;
    bottom: 1.5rem;
    right: 0rem;

    padding: .5rem;

    // lightyellow
    // background-color: hsla(60,100%,90%,.30);
    // background-color: rgba(var(--color-surface-500) / .5);

    border-top: solid thin hsla(0,0%,0%,.25);
    border-left: solid thin hsla(0,0%,0%,.25);
    border-bottom: solid thin hsla(0,0%,0%,.25);
    border-top-left-radius: .5em;
    border-bottom-left-radius: .5em;

    opacity: .15;
    // opacity: 1;

    font-size: .75rem;

    z-index: 5;

    // NOTE: transition when no longer hovering
    transition-property: opacity, background-color;
    transition-delay: 1.25s;
    transition-duration: .75s;
    transition-timing-function: ease-out;
}
*/

    /*
#xxx-AE-Quick-Access-Type:hover {

    border-top: solid thin hsla(0,0%,0%,.95);
    border-left: solid thin hsla(0,0%,0%,.95);
    border-bottom: solid thin hsla(0,0%,0%,.95);

    opacity: 1;

    // NOTE: transition when hover starts
    transition-property: opacity, background-color;
    transition-delay: .5s;
    transition-duration: .25s;
    transition-timing-function: ease-in;
}
*/

    /* #Access-Type .unlock_text {
    transition: width 2s, height 2s, background-color 2s, transform 2s;
} */
    /* END: Svelte Access Type component  */

    .access_type_unlock_btn:hover .lock_icon {
        display: none;
    }

    .access_type_unlock_btn:hover .unlock_icon {
        display: initial;
    }

    .access_type_unlock_btn .unlock_text {
        display: none;
    }

    .access_type_unlock_btn:hover .unlock_text {
        display: initial;
        /* outline: solid thin red; */
    }

    /*
.ae_access_type .current_text {
    display: none;
}

.ae_access_type:hover .current_text {
    display: initial;
    outline: solid thin red;
}
*/
</style>
