<script lang="ts">
    let log_lvl: number = $state(1);
    interface Props {
        /** @type {import('./$types').LayoutData} */
        data: any;
        children?: import('svelte').Snippet;
    }

    let { data, children }: Props = $props();

    // *** Import Svelte specific
    // import { onMount, tick } from 'svelte';
    import { goto } from '$app/navigation';
    import { sineIn } from 'svelte/easing';

    // *** Import other supporting libraries
    import { liveQuery } from 'dexie';
    import { Drawer, Footer, Modal } from 'flowbite-svelte';
    import { listen, idle, onIdle, restartCountdown } from 'svelte-idle';

    import {
        // Brain,
        // House, Library,
        LoaderCircle,
        // RefreshCw,
        Satellite
    } from '@lucide/svelte';

    // *** Import Aether specific variables and functions
    import type { key_val } from '$lib/stores/ae_stores';
    import { ae_util } from '$lib/ae_utils/ae_utils';
    import { api } from '$lib/api/api';
    import { db_events } from '$lib/ae_events/db_events';
    import {
        ae_snip,
        ae_loc,
        ae_sess,
        ae_api,
        ae_trig,
        slct,
        slct_trigger,
        time
    } from '$lib/stores/ae_stores';
    import {
        events_loc,
        events_sess,
        events_slct,
        events_trigger,
        events_trig
    } from '$lib/stores/ae_events_stores';
    import { events_func } from '$lib/ae_events_functions';

    import Launcher_cfg from '../launcher_cfg.svelte';
    import Launcher_menu from '../launcher_menu.svelte';
    import Launcher_session_view from '../launcher_session_view.svelte';
    import Element_websocket_v2 from '$lib/elements/element_websocket_v2.svelte';

    // *** Set initial variables
    let ae_acct = data[$slct.account_id];

    import { online } from 'svelte/reactivity/window';

    $ae_sess.disable_sys_nav = true;
    $ae_sess.disable_sys_header = true;
    $ae_sess.disable_sys_footer = true;

    if (!$events_loc?.launcher) {
        $events_loc.launcher = {
            app_mode: 'default',
            controller: 'local',
            controller_group_code: 'launcher-00',
            ws_connect: false,
            hide_drawer__cfg: true,
            hide_drawer__debug: true
        };
    }

    if (log_lvl) {
        console.log(`event_id: ${data.params.event_id}`);
        console.log(`event_location_id: ${data.params.event_location_id}`);
        console.log(
            `event_session_id: ${data.url.searchParams.get('session_id')}`
        );
    }
    $events_slct.event_id = data.params.event_id;
    $events_slct.event_location_id = data.params.event_location_id;
    $events_slct.event_session_id = data.url.searchParams.get('session_id');

    // String-Only ID Vision: Sync the device ID from the native environment
    const native_dev = $ae_loc.native_device;
    if (native_dev) {
        $events_slct.event_device_id =
            native_dev.event_device_id ||
            native_dev.id ||
            native_dev.event_device_id_random ||
            native_dev.id_random;
    }

    $events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li ?? [
        ''
    ];
    $events_slct.id_li__event_location = ae_acct.slct.id_li__event_location ?? [
        ''
    ];

    // *** Functions and Logic

    // Event
    let lq__event_obj = liveQuery(async () => {
        const id = $events_slct?.event_id;
        if (!id) return null;
        if (log_lvl > 1) console.log(`lq__event_obj: event_id = ${id}`);
        let results = await db_events.event.get(id);

        if ($events_slct.event_obj && results) {
            if (
                JSON.stringify($events_slct.event_obj) !==
                JSON.stringify(results)
            ) {
                $events_slct.event_obj = { ...results };
            }
        }
        return results;
    });

    // Event Device
    let lq__event_device_obj = liveQuery(async () => {
        const id = $events_slct.event_device_id;
        if (!id) return null;
        let results = await db_events.device.get(id);
        if ($events_slct.event_device_obj && results) {
            if (
                JSON.stringify($events_slct.event_device_obj) !==
                JSON.stringify(results)
            ) {
                $events_slct.event_device_obj = { ...results };
            }
        }
        return results;
    });

    // Event File - For Event
    let lq__event_event_file_obj_li = liveQuery(async () => {
        const id = $events_slct.event_id;
        if (!id) return [];
        return await db_events.file
            .where('for_id')
            .equals(id)
            .sortBy('filename');
    });

    // Event File - For Location
    let lq__location_event_file_obj_li = liveQuery(async () => {
        const id = $events_slct.event_location_id;
        if (!id) return [];
        return await db_events.file
            .where('for_id')
            .equals(id)
            .sortBy('filename');
    });

    // Event Location
    let lq__event_location_obj = liveQuery(async () => {
        const id = $events_slct.event_location_id;
        if (!id) return null;
        return await db_events.location.get(id);
    });

    let lq__event_location_obj_li = liveQuery(async () => {
        const id = $events_slct.event_id;
        if (!id) return [];
        return await db_events.location
            .where('event_id')
            .equals(id)
            .sortBy('name');
    });

    // Event Session (Main View Trigger)
    // Removed $derived wrapper to ensure stable observable subscription in Svelte 5
    let lq__event_session_obj = liveQuery(async () => {
        const id = $events_slct.event_session_id;
        if (!id) return null;
        if (log_lvl)
            console.log(
                `🔍 [Trace] Launcher Layout LQ: Fetching session_id=${id}`
            );
        const start = performance.now();
        let results = await db_events.session.get(id);
        if (log_lvl)
            console.log(
                `📦 [Trace] Launcher Layout LQ: Result obtained in ${(performance.now() - start).toFixed(2)}ms (Result=${results?.name || 'NOT FOUND'})`
            );
        return results;
    });

    let lq__event_session_obj_li = liveQuery(async () => {
        const id = $events_slct.event_location_id;
        if (!id) return [];
        if (log_lvl > 1)
            console.log(
                `LQ - Using default sort for Event Session list location_id: ${id}`
            );
        let results = await db_events.session
            .where('event_location_id')
            .equals(id)
            .reverse()
            .sortBy('name');

        if (
            $events_slct.event_session_obj_li &&
            JSON.stringify($events_slct.event_session_obj_li) !==
                JSON.stringify(results)
        ) {
            $events_slct.event_session_obj_li = [...(results || [])];
        }
        return results;
    });

    let trigger_handle_ws_conn = $state(false);
    let trigger_handle_ws_recv = $state(false);
    let trigger_handle_ws_sent = $state(false);

    /* *** BEGIN *** Handle WebSocket events */
    function handle_ws_conn(ws_conn_status: any) {
        if (log_lvl) console.log('*** handle_ws_conn() ***', ws_conn_status);
        if (ws_conn_status.status == 'connected') {
            $events_sess.launcher.ws = { status: 'connected' };
        } else {
            $events_sess.launcher.ws = { status: 'disconnected' };
        }
    }

    function handle_ws_recv(ws_recv_status: any) {
        if (log_lvl) console.log('*** handle_ws_recv() ***', ws_recv_status);
        if (ws_recv_status.type == 'cmd' && ws_recv_status.cmd) {
            let cmd = ws_recv_status.cmd;
            if ($events_loc.launcher.controller != 'remote') return;

            if (cmd.startsWith('ae_load:')) {
                let cmd_parts = cmd.split(':');
                let obj_parts = cmd_parts[1].split('=');
                let obj_type = obj_parts[0];
                let obj_id = obj_parts[1];

                if (obj_type == 'event_session') {
                    $events_slct.event_session_id = obj_id;
                    let new_url = new URL(data.url);
                    new_url.pathname = `/events/${$lq__event_session_obj?.event_id}/launcher/${$lq__event_session_obj?.event_location_id}`;
                    new_url.searchParams.set(
                        'session_id',
                        $events_slct.event_session_id
                    );
                    goto(new_url.toString(), { replaceState: false });
                }
            } else if (cmd.startsWith('ae_download:')) {
                let cmd_parts = cmd.split(':');
                let obj_parts = cmd_parts[1].split('=');
                let obj_type = obj_parts[0];
                let obj_id = obj_parts[1];
                let obj_filename = cmd_parts[2];

                api.get_object({
                    api_cfg: $ae_api,
                    endpoint: `/v3/action/hosted_file/${obj_id}/download`,
                    params: {
                        filename: obj_filename,
                        key: $ae_api.account_id
                    },
                    return_blob: true,
                    auto_download: true,
                    log_lvl: 1
                });
            } else if (cmd.startsWith('ae_open:')) {
                let cmd_parts = cmd.split(':');
                let obj_parts = cmd_parts[1].split('=');
                let obj_id = obj_parts[1];

                if (obj_parts[0] == 'event_file') {
                    $events_sess.launcher.modal__open_event_file_id = null;
                    clearInterval(idle_timer_interval);
                    saver_looping = false;
                    restartCountdown();
                    $events_slct.event_file_id = obj_id;
                    $events_sess.launcher.modal__open_event_file_id = obj_id;
                }
            } else if (cmd.startsWith('ae_close:')) {
                if (cmd.split(':')[1] == 'event_file_modal') {
                    $events_sess.launcher.modal__open_event_file_id = null;
                }
                clearInterval(idle_timer_interval);
                saver_looping = false;
                restartCountdown();
            } else if (cmd.startsWith('ae_refresh:')) {
                if (cmd.split(':')[1] == 'now') location.reload();
            }
        }
    }

    function handle_ws_sent(ws_sent_status: any) {
        $events_sess.launcher.controller_cmd = null;
        $events_sess.launcher.controller_trigger_send = null;
    }

    $effect(() => {
        if (trigger_handle_ws_conn) {
            handle_ws_conn(trigger_handle_ws_conn);
            trigger_handle_ws_conn = false;
        }
    });

    $effect(() => {
        if (trigger_handle_ws_recv) {
            handle_ws_recv(trigger_handle_ws_recv);
            trigger_handle_ws_recv = false;
        }
    });

    $effect(() => {
        if (trigger_handle_ws_sent) {
            handle_ws_sent(trigger_handle_ws_sent);
            trigger_handle_ws_sent = false;
        }
    });

    if (!$events_loc.launcher.idle_timer)
        $events_loc.launcher.idle_timer = 5 * 60 * 1000;
    if (!$events_loc.launcher.idle_cycle)
        $events_loc.launcher.idle_cycle = 5 * 1000;
    if (!$events_loc.launcher.idle_loop_period)
        $events_loc.launcher.idle_loop_period = 3 * 60 * 1000;

    listen({
        timer: $events_loc.launcher.idle_timer,
        cycle: $events_loc.launcher.idle_cycle
    });

    let idle_timer_interval: any = $state();
    let saver_looping: boolean = $state(false);

    function handle_idle_client() {
        if (
            $lq__event_session_obj &&
            $lq__event_session_obj?.type_code == 'poster'
        ) {
            if (saver_looping) return false;
            saver_looping = true;

            idle_timer_interval = setInterval(
                () => {
                    if ($events_loc.launcher.screen_saver_img_kv) {
                        const keys = Object.keys(
                            $events_loc.launcher.screen_saver_img_kv
                        );
                        const rand_index = Math.floor(
                            Math.random() * keys.length
                        );
                        let event_file_obj =
                            $events_loc.launcher.screen_saver_img_kv[
                                keys[rand_index]
                            ];

                        $events_slct.event_file_id =
                            event_file_obj.event_file_id;
                        $events_slct.event_file_obj = event_file_obj;
                        $events_sess.launcher.modal__open_event_file_id = null;
                        $events_sess.launcher.modal__title =
                            event_file_obj.filename ?? '*';
                        $events_sess.launcher.modal__open_event_file_id =
                            $events_slct.event_file_id;
                        $events_sess.launcher.modal__event_file_obj =
                            event_file_obj;
                        return true;
                    }
                    return false;
                },
                $events_loc.launcher.idle_loop_period ?? 2 * 60 * 1000
            );
        } else {
            saver_looping = false;
            return false;
        }
    }

    onIdle(() => {
        clearInterval(idle_timer_interval);
        handle_idle_client();
    });

    $effect(() => {
        if (!$idle) {
            clearInterval(idle_timer_interval);
            saver_looping = false;
        }
    });
</script>

<svelte:head>
    <title>
        &AElig;:
        {$lq__event_location_obj?.name ?? '-- not set --'}
        ({$lq__event_session_obj?.name ?? 'Æ loading...'}) - Launcher v3 -
        {$events_loc?.title}
    </title>
</svelte:head>

<div
    class="
        static
        m-auto
        border-x border-gray-200 dark:border-gray-600
        mt-4 mb-16 sm:mb-12
        h-full
        w-full max-w-7xl
        transition-all
        "
>
    <header
        id="Main-Header"
        class:hidden={$events_loc.launcher.hide__launcher_header}
        class="
        z-20
        absolute top-0 left-0 right-0
        w-full max-w-7xl
        h-12
        p-1 px-12 m-auto

        flex flex-row items-center justify-around sm:justify-between

        text-sm hover:text-base

        bg-slate-200

        opacity-90 hover:opacity-100
        transition-all duration-1000
        "
    >
        <h3 class="h4 text-center italic text-surface-600-400">
            <button
                type="button"
                class=""
                onclick={() => {
                    $events_loc.launcher.hide__launcher_menu =
                        !$events_loc.launcher.hide__launcher_menu;
                }}
                title="Toggle Launcher menu"
            >
                <Satellite class="text-base mx-1 inline-block text-gray-500" />
                <abbr title="Aether - Events Module Launcher">
                    Æ Launcher
                    <span
                        class="text-xs align-super font-normal"
                        title="Version 3">v3</span
                    >
                </abbr>
            </button>
        </h3>

        {#if $lq__event_obj}
            <h2
                class="hidden md:inline-block h3 text-center text-surface-600-400"
            >
                {$lq__event_obj.cfg_json?.short_name}
            </h2>
            <h3
                class="h4 text-center italic text-surface-600-400"
                title="Location ID: {$lq__event_location_obj?.event_location_id} Name: {$lq__event_location_obj?.name}"
            >
                <button
                    type="button"
                    class="text-base"
                    onclick={() => {
                        $ae_loc.edit_mode = !$ae_loc.edit_mode;
                    }}
                    title="Toggle Edit Mode to show location options and more"
                >
                    <span class="fas fa-map-marker-alt"></span>
                    <span class="sr-only">Location:</span>
                </button>
                {$lq__event_location_obj?.name}
            </h3>
        {:else}
            <div class="flex flex-row gap-1 items-center justify-center">
                <span class="fas fa-spinner fa-spin mx-1"></span>
                <span>Loading event...</span>
            </div>
        {/if}
    </header>

    <div
        class="
        h-full min-w-full w-full max-w-full
        flex flex-col sm:flex-row flex-wrap sm:flex-nowrap gap-0
        items-center
        justify-start sm:justify-center
        py-1 px-0.5
        bg-gray-100

        "
    >
        <section
            id="Main-Nav-Menu"
            class="event_launcher_menu
        h-full
        basis-1/5
        min-w-56 md:min-w-64 lg:min-w-72
        max-w-xs
        pt-0.5 pr-0.5
        flex flex-col gap-1 items-center justify-start

        border-r border-gray-200 dark:border-gray-700
        hover:bg-surface-100-900
        "
            class:hidden={$events_loc.launcher.hide__launcher_menu}
        >
            <Launcher_menu
                data_url={data.url}
                {lq__event_obj}
                {lq__event_event_file_obj_li}
                {lq__location_event_file_obj_li}
                slct__event_file_id={$events_slct.event_file_id}
                {lq__event_location_obj_li}
                {lq__event_location_obj}
                slct__event_location_id={$events_slct.event_location_id}
                bind:loading__session_li_status={
                    $events_sess.launcher.loading__session_li_status
                }
                {lq__event_session_obj_li}
                bind:loading__session_id_status={
                    $events_sess.launcher.loading__session_id_status
                }
                {lq__event_session_obj}
                bind:slct__event_session_id={$events_slct.event_session_id}
                bind:trigger_reload__event_session_obj_id={
                    $events_sess.launcher.trigger_reload__event_session_obj_id
                }
                bind:trigger_reload__event_session_obj_li={
                    $events_sess.launcher.trigger_reload__event_session_obj_li
                }
                bind:trigger_reload__event_location_obj_li={
                    $events_sess.launcher.trigger_reload__event_location_obj_li
                }
            ></Launcher_menu>
        </section>

        <section
            id="Main-Content"
            class="event_launcher_main
        h-full
        min-w-xs
        max-w-full
        py-1 px-0.5
        basis-4/5
        flex flex-col gap-1
        items-center
        justify-center
        overflow-y-auto
        "
        >
            {#if !$events_slct.event_location_id}
                <div
                    class="flex flex-row items-center justify-center p-8 opacity-50"
                >
                    <span class="fas fa-map-marker-alt mx-2 text-2xl"></span>
                    <span>Please select a location from the menu</span>
                </div>
            {/if}

            {#if $events_slct.event_session_id && $lq__event_session_obj}
                <Launcher_session_view
                    bind:slct__event_session_id={$events_slct.event_session_id}
                    {lq__event_session_obj}
                    bind:type_code={$lq__event_session_obj.type_code}
                ></Launcher_session_view>
            {:else if $events_slct.event_session_id}
                <div
                    class="flex flex-col items-center justify-center p-8 opacity-50"
                >
                    <LoaderCircle class="animate-spin mb-2" />
                    <span>Loading session details...</span>
                </div>
            {/if}
        </section>
    </div>

    {@render children?.()}
</div>

<footer
    id="Main-Footer"
    class:hidden={$events_loc.launcher.hide__launcher_footer}
    class="
        z-20
        absolute bottom-0 left-0 right-0
        w-full max-w-7xl
        p-1 m-auto

        flex flex-row items-center justify-between
        sm:flex-row md:items-center md:justify-between

        text-xs hover:sm:text-sm hover:md:text-base hover:lg:text-lg


        bg-gray-200 border-t border-gray-200
        dark:bg-gray-800 dark:border-gray-600

        opacity-50 hover:opacity-100
        transition-all duration-1000
        "
>
    <div
        class="slct_location_name transition-all duration-1000"
        title="Location ID: {$lq__event_location_obj?.event_location_id} Name: {$lq__event_location_obj?.name} | Device ID: {$lq__event_device_obj?.event_device_id} Name: {$lq__event_device_obj?.name}"
    >
        <button
            type="button"
            class=""
            onclick={() => {
                $ae_loc.edit_mode = !$ae_loc.edit_mode;
            }}
            title="Toggle Edit Mode to show location options and more"
        >
            <span class="sr-only">Location:</span>
            <span class="fas fa-map-marker-alt"></span>
        </button>
        {$lq__event_location_obj?.name}
        {#if $lq__event_device_obj?.name}
            <span class="fas fa-laptop mx-1"></span>
            {$lq__event_device_obj?.name}
        {/if}
    </div>

    <span
        class:preset-tonal-warning={!$idle}
        class:preset-tonal-success={$idle}
        class="group px-1 rounded-md transition-all duration-1000"
        title="The user is currently {$idle ? 'idle' : 'active'}"
    >
        {#if $idle}
            <span class="fas fa-bed mx-1"></span>
            <span class="hidden group-hover:inline"> Idle </span>
        {:else}
            <span class="fas fa-mouse-pointer mx-1"></span>
            <span class="hidden group-hover:inline"> Active </span>
        {/if}
    </span>

    <span
        class="group px-1 rounded-md transition-all duration-1000"
        title="Online status = {online?.current}"
    >
        <span class="fas fa-wifi mx-1"></span>
        {online?.current ? '' : 'Offline!'}
    </span>

    <span
        class:hidden={!$events_loc.launcher.ws_connect}
        class:preset-tonal-warning={$events_sess.launcher.ws_connect_status !=
            'connected'}
        class:preset-tonal-success={$events_sess.launcher.ws_connect_status ==
            'connected'}
        class="group px-1 rounded-md transition-all duration-1000"
        title="WebSocket is {$events_sess.launcher.ws_connect_status ==
        'connected'
            ? 'connected'
            : 'disconnected'} API: {$ae_api?.base_url}"
    >
        {#if $events_sess.launcher.ws_connect_status == 'connected'}
            <span class="fas fa-sitemap mx-1 text-green-700"></span>
            <span class="hidden group-hover:inline"> WS Connected </span>
        {:else}
            <span class="fas fa-times mx-1"></span>
            <span class="hidden group-hover:inline"> WS Disconnected </span>
        {/if}
    </span>

    <div
        class="current_datetime font-mono px-2 hover:font-bold hover:bg-white transition-all"
    >
        <span class="hidden md:inline">
            <span class="fas fa-calendar-alt"></span>
            {ae_util.iso_datetime_formatter($time, 'date_full_no_year')}
        </span>
        <span class="hidden sm:inline">
            <span class="fas fa-clock"></span>
        </span>
        {#if $events_loc.launcher?.time_hours == 12}
            {ae_util.iso_datetime_formatter($time, 'time_12_long')}
        {:else}
            {ae_util.iso_datetime_formatter($time, 'time_long')}
        {/if}
    </div>
</footer>

<div class="absolute top-0 left-0 z-20 text-center">
    <button
        type="button"
        onclick={() => ($events_loc.launcher.hide_drawer__cfg = false)}
        class="btn btn-sm p-2.5 preset-tonal-error hover:preset-filled-error-500 transition-all duration-1000"
        class:opacity-25={!$ae_loc.trusted_access}
        class:hover:opacity-75={!$ae_loc.trusted_access}
    >
        <span class="fas fa-biohazard"></span>
        <span class="hidden">Launcher Config</span>
    </button>
</div>

<Drawer
    class="bg-orange-100 opacity-90 hover:opacity-97 transition-all duration-1000 border border-gray-300 dark:border-gray-600 w-full md:w-96 lg:w-[32rem]"
    placement="left"
    transitionType="fly"
    transitionParams={{
        x: -520,
        duration: 200,
        easing: sineIn
    }}
    bind:hidden={$events_loc.launcher.hide_drawer__cfg}
    id="sidebar1"
>
    <Launcher_cfg></Launcher_cfg>

    <hr class="my-2 border-gray-300 dark:border-gray-600" />

    <div
        class="flex flex-row flex-wrap gap-0.5 items-center justify-center max-w-md"
    >
        <a
            href="/events/{$events_slct.event_id}"
            class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
        >
            <span class="fas fa-search m-1"></span>
            Session Search
        </a>
        {#if $events_slct?.event_location_id}
            <a
                href="/events/{$events_slct.event_id}/location/{$events_slct.event_location_id}"
                class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
            >
                <span class="fas fa-map-marker m-1"></span>
                View Selected Location
            </a>
        {/if}
        {#if $events_slct?.event_session_id}
            <a
                href="/events/{$events_slct.event_id}/session/{$events_slct.event_session_id}"
                class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
            >
                <span class="fas fa-chalkboard-teacher m-1"></span>
                View Selected Session
            </a>
        {/if}
    </div>
</Drawer>

<Drawer
    activateClickOutside={false}
    class="bg-red-100 opacity-75 hover:opacity-95 transition-all duration-1000"
    placement="bottom"
    transitionType="fly"
    transitionParams={{
        y: 320,
        duration: 200,
        easing: sineIn
    }}
    bind:hidden={$events_loc.launcher.hide_drawer__debug}
    id="sidebar2"
>
    <div class="flex flex-row items-center justify-between">
        <h2
            class="text-center mb-4 text-base font-semibold text-gray-500 dark:text-gray-400"
        >
            Debug
        </h2>
        <button
            type="button"
            onclick={() => ($events_loc.launcher.hide_drawer__debug = true)}
            class="mb-4 dark:text-white"
        >
            <span class="fas fa-times"></span>
            <span class="hidden">Close Debug Drawer</span>
        </button>
    </div>

    <div>
        <pre class="text-xs">
        {JSON.stringify($events_loc.launcher, null, 2)}
    </pre>
        <hr />
        <pre class="text-xs">
        {JSON.stringify($ae_api, null, 2)}
    </pre>
    </div>
</Drawer>

<Modal
    open={$events_sess.launcher?.modal__open_event_file_id}
    autoclose={false}
    placement="top-center"
    class="
        bg-gray-500/90 dark:bg-gray-800/90 text-gray-800 dark:text-gray-200
        rounded-lg border-gray-200 dark:border-gray-700
        divide-y divide-gray-200 dark:divide-gray-700 shadow-md
        relative
        flex flex-col items-center justify-center
        {$events_loc.launcher.controller == 'remote' ? 'min-h-full' : ''}
        min-w-full
        "
    bodyClass="p-0 space-y-0 overflow-y-auto flex flex-col gap-1 items-center justify-center"
    headerClass={`fixed top-0 right-0 left-0 p-1 md:p-2 flex flex-row items-center ${$events_loc.launcher.controller == 'remote' ? 'hidden' : ''} bg-white dark:bg-gray-800 opacity-50 ${$events_loc.launcher.hide__modal_header_title ? 'justify-center' : 'justify-between'}`}
    footerClass="text-center hidden"
>
    {#snippet header()}
        <h3
            class:hidden={$events_loc.launcher.hide__modal_header_title}
            class="text-lg font-semibold opacity-20 hover:opacity-100 transition-all"
        >
            {$events_sess.launcher?.modal__title ?? 'Digital Poster Display'}
        </h3>
        <button
            type="button"
            class="btn flex-row-reverse group transition-all justify-self-end"
            onclick={() => {
                $events_sess.launcher.modal__open_event_file_id = null;
            }}
            title="Close Modal"
        >
            <span class="fas fa-times my-1.5"></span>
            <span class="hidden group-hover:inline"> Close</span>
        </button>
    {/snippet}

    <button
        type="button"
        onclick={() => {
            $events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
            $events_sess.launcher.controller_trigger_send = true;
        }}
        class="
            absolute top-0 right-12
            m-1 p-1
            btn btn-sm
            preset-tonal-error preset-outlined-error hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
        class:hidden={$events_loc.launcher.controller != 'local_push' ||
            $events_sess.launcher.ws_connect_status != 'connected'}
        title="Close the remote device's display of the poster"
    >
        <span class="fas fa-times m-1"></span>
        <span class="fas fa-tv"></span>
        Close Remote Poster Display Only
    </button>

    {#if $events_sess.launcher.modal__open_event_file_id}
        <img
            src="{$ae_api.base_url}/v3/action/event_file/{$events_sess.launcher
                .modal__open_event_file_id}/download?filename={$events_slct
                .event_file_obj.filename}&key={$ae_api.account_id}"
            alt="Poster"
            class="min-h-28 min-w-md max-h-full max-w-full"
        />
    {:else}
        <div class="flex flex-row items-center justify-center p-4">
            <span class="fas fa-info-circle mx-1"></span>
            <span>No image selected</span>
        </div>
    {/if}

    <button
        type="button"
        onclick={() => {
            $events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
            $events_sess.launcher.controller_trigger_send = true;
        }}
        class="
            absolute bottom-0 left-12
            m-1 p-1
            btn btn-sm
            preset-tonal-error preset-outlined-error hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
        class:hidden={$events_loc.launcher.controller != 'local_push' ||
            $events_sess.launcher.ws_connect_status != 'connected'}
        title="Close the remote device's display of the poster"
    >
        <span class="fas fa-times m-1"></span>
        <span class="fas fa-tv"></span>
        Close Remote Poster Display Only
    </button>

    <button
        type="button"
        onclick={() => {
            $events_sess.launcher.modal__title = '';
            $events_sess.launcher.modal__open_event_file_id = null;
            $events_sess.launcher.modal__event_file_obj = null;
        }}
        class="
            absolute bottom-0 right-12
            m-1 p-1
            btn btn-sm
            preset-tonal-success preset-outlined-success hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
        class:hidden={!$ae_loc.trusted_access &&
            ($events_loc.launcher.controller != 'local_push' ||
                $events_sess.launcher.ws_connect_status != 'connected')}
        title="Close this controller's local modal display of this poster"
    >
        <span class="fas fa-times m-1"></span>
        <span class="fas fa-list"></span>
        Close Poster on This Device
    </button>
</Modal>

{#if $events_loc.launcher.controller_group_code && $events_loc.launcher.ws_connect}
    <Element_websocket_v2
        {log_lvl}
        bind:ws_connect={$events_loc.launcher.ws_connect}
        bind:ws_connect_status={$events_sess.launcher.ws_connect_status}
        ws_server={$ae_api.fqdn}
        bind:group_id={$events_loc.launcher.controller_group_code}
        bind:client_id={$events_loc.launcher.controller_client_id}
        bind:cmd={$events_sess.launcher.controller_cmd}
        type={'cmd'}
        bind:trigger_send={$events_sess.launcher.controller_trigger_send}
        bind:trigger_connect={$events_sess.launcher.trigger__ws_connect}
        bind:trigger_disconnect={$events_sess.launcher.trigger__ws_disconnect}
        bind:hide__ws_element={$events_loc.launcher.hide__ws_element}
        bind:hide__ws_form={$events_loc.launcher.hide__ws_form}
        bind:hide__ws_messages={$events_loc.launcher.hide__ws_messages}
        bind:hide__ws_commands={$events_loc.launcher.hide__ws_commands}
        bind:ws_conn_status={trigger_handle_ws_conn}
        bind:ws_recv_status={trigger_handle_ws_recv}
        bind:ws_sent_status={trigger_handle_ws_sent}
    />
{/if}
