<script lang="ts">
/**
 * menu_launcher_controls.svelte — Aether Launcher: Bottom Control Bar
 *
 * PURPOSE:
 *   Accessibility and visibility controls for the Launcher sidebar. Placed at the
 *   bottom of launcher_menu.svelte so presenters and operators can adjust display
 *   settings without needing access to the global AE System Menu (which may be
 *   unavailable in kiosk, locked, or podium setups).
 *
 * SECTIONS:
 *   1. Visibility toggles (edit mode only) — show/hide draft files and hidden sessions
 *   2. Accessibility controls (always visible) — Reset Apps, font size cycler, light/dark toggle
 *
 * WHY ALWAYS-VISIBLE ACCESSIBILITY CONTROLS:
 *   Projector-connected screens, tablets, and phones at conference venues vary wildly
 *   in lighting. Operators and presenters need quick one-tap access to font size and
 *   theme mode without hunting through the system menu or requiring admin access.
 *
 * WHY RESET APPS IS ALWAYS VISIBLE:
 *   If a presentation app (PowerPoint, Keynote, etc.) hangs or stalls on stage, the
 *   presenter needs a one-tap way to force-close it and recover — without entering edit
 *   mode or navigating the config menu. This button is intentionally prominent.
 */

import { Moon, Sun, Eye, EyeOff, Columns2, Copy, XCircle, Trash, Recycle } from '@lucide/svelte';

import { ae_loc } from '$lib/stores/ae_stores';
import { launcher_loc } from '$lib/stores/ae_events_stores__launcher.svelte';
import * as native from '$lib/electron/electron_relay';

interface Props {
    log_lvl?: number;
}

let { log_lvl = $bindable(0) }: Props = $props();

// Persist display mode across reloads — reflects the last-set state, not hardware-queried state.
let quick_display_mode = $state<'extend' | 'mirror'>(
    (launcher_loc.current as any)?.display_mode ?? 'extend'
);

const is_native_launcher_mode = $derived(
    !!$ae_loc.is_native && launcher_loc.current.app_mode === 'native'
);

async function toggle_display_mode() {
    const next = quick_display_mode === 'extend' ? 'mirror' : 'extend';
    if (is_native_launcher_mode) {
        const res = await native.set_display_layout({ mode: next });
        if (res?.success) {
            quick_display_mode = next;
            (launcher_loc.current as any).display_mode = next;
        }
    } else {
        quick_display_mode = next;
        (launcher_loc.current as any).display_mode = next;
    }
}

// Process names closed when presenter hits "Reset Apps". Covers the standard
// conference app set. Override per device via event_device.other_json.launcher.kill_process_li.
const DEFAULT_KILL_LIST = [
    'Microsoft PowerPoint',
    'Keynote',
    'Adobe Acrobat Reader DC',
    'VLC',
    'soffice'
];

let reset_apps_status = $state('');
let cache_status = $state('');

async function handle_reset_apps() {
    const native_device = ($ae_loc as any).native_device ?? null;
    const process_name_li: string[] =
        native_device?.other_json?.launcher?.kill_process_li ?? DEFAULT_KILL_LIST;
    reset_apps_status = 'Resetting...';
    await native.kill_processes({ process_name_li });
    reset_apps_status = 'Done';
    setTimeout(() => (reset_apps_status = ''), 3000);
}

async function handle_cache_cleanup() {
    cache_status = 'Clearing...';
    try {
        localStorage.removeItem('ae_events_loc');
        localStorage.removeItem('ae_loc');
        indexedDB.deleteDatabase('ae_events_db');
        cache_status = 'Done — reloading...';
        setTimeout(() => window.location.reload(), 800);
    } catch {
        cache_status = 'Error';
        setTimeout(() => (cache_status = ''), 3000);
    }
}

function handle_reload_launcher() {
    if ($ae_loc.is_native) {
        native.window_control({ action: 'reload' });
    } else {
        window.location.reload();
    }
}
</script>

<div class="flex flex-row flex-wrap w-full max-w-full items-center justify-center gap-0.5">

    <!-- All Files / All Sessions toggles.
            Warning color when showing hidden content — signals non-default state to operators. -->
    <div class="min-w-32 flex flex-row flex-wrap items-center justify-center gap-0.5">
        <button
            type="button"
            onclick={() => {
                if (launcher_loc.current.show_content__hidden_files) {
                    launcher_loc.current.show_content__hidden_files = false;
                    launcher_loc.current.show_content__internal_files = false;
                } else {
                    launcher_loc.current.show_content__hidden_files = true;
                    launcher_loc.current.show_content__internal_files = true;
                }
            }}
            class="btn btn-sm min-w-34 w-34 max-w-1/2 text-xs transition-all"
            class:preset-tonal-warning={launcher_loc.current.show_content__hidden_files}
            class:hover:preset-filled-warning-500={launcher_loc.current
                .show_content__hidden_files}
            class:preset-tonal-tertiary={!launcher_loc.current.show_content__hidden_files}
            class:hover:preset-filled-tertiary-500={!launcher_loc.current
                .show_content__hidden_files}
            title={launcher_loc.current.show_content__hidden_files
                ? 'Showing all files including hidden and draft. Tap to hide them again.'
                : 'Showing only public files. Tap to show all files including hidden and draft.'}>
            {#if launcher_loc.current.show_content__hidden_files}
                <EyeOff size="0.85em" class="m-1" />
                Hide Files
            {:else}
                <Eye size="0.85em" class="m-1" />
                All Files
            {/if}
        </button>

        {#if $ae_loc.edit_mode}
        <button
            type="button"
            onclick={() => {
                launcher_loc.current.show_content__hidden_sessions =
                    !launcher_loc.current.show_content__hidden_sessions;
            }}
            class="btn btn-sm min-w-34 w-34 max-w-1/2 text-xs transition-all"
            class:preset-tonal-warning={launcher_loc.current.show_content__hidden_sessions}
            class:hover:preset-filled-warning-500={launcher_loc.current
                .show_content__hidden_sessions}
            class:preset-tonal-tertiary={!launcher_loc.current.show_content__hidden_sessions}
            class:hover:preset-filled-tertiary-500={!launcher_loc.current
                .show_content__hidden_sessions}
            title={launcher_loc.current.show_content__hidden_sessions
                ? 'Showing all sessions including cancelled and hidden. Tap to hide them again.'
                : 'Showing only active sessions. Tap to show all sessions including hidden and cancelled.'}>
            {#if launcher_loc.current.show_content__hidden_sessions}
                <EyeOff size="0.85em" class="shrink-0" />
                Hide Sessions
            {:else}
                <Eye size="0.85em" class="shrink-0" />
                All Sessions
            {/if}
        </button>
        {/if}
    </div>

    <div class="min-w-32 flex flex-row flex-wrap items-center justify-center gap-0.5">
        <!-- Display mode toggle — warning color when mirroring (non-default operator setting).
            Tooltip describes the CURRENT state and what pressing will do, so operators know
            which way they are switching before they tap. -->
        <button
            type="button"
            onclick={toggle_display_mode}
            class="btn btn-sm min-w-34 w-34 max-w-1/2 text-xs transition-all"
            class:preset-tonal-tertiary={quick_display_mode === 'extend'}
            class:hover:preset-filled-tertiary-500={quick_display_mode === 'extend'}
            class:preset-tonal-warning={quick_display_mode === 'mirror'}
            class:hover:preset-filled-warning-500={quick_display_mode === 'mirror'}
            title={quick_display_mode === 'extend'
                ? 'Screens are extended: laptop can show notes while projector shows slides. Tap to mirror — make both screens show the same content.'
                : 'Screens are mirrored: both screens show the same content. Tap to extend — allow the laptop and projector to show different content.'}>
            {#if quick_display_mode === 'extend'}
                <Columns2 size="0.85em" class="shrink-0" />
                Display: Extend
            {:else}
                <Copy size="0.85em" class="shrink-0" />
                Display: Mirror
            {/if}
        </button>
    </div>


    <!-- ── Always-visible controls ── -->
    <div class="w-full flex flex-row flex-wrap items-center justify-center gap-0.5">

        {#if $ae_loc.edit_mode}
        <button
            type="button"
            onclick={handle_cache_cleanup}
            class="btn btn-sm preset-tonal-error hover:preset-filled-error-500 w-34 max-w-1/2 text-xs transition-all"
            title="Clear localStorage and IDB caches used by the Launcher. Does *not* delete cached files."
            >
            <Trash size="0.85em" class="shrink-0" />
            {cache_status || 'Clear Cache'}
        </button>
        {/if}

        <button
            type="button"
            onclick={handle_reload_launcher}
            class="btn btn-sm preset-tonal-error hover:preset-filled-error-500 w-34 max-w-1/2 text-xs transition-all"
            title="Reload the Launcher interface."
            >
            <Recycle size="0.85em" class="shrink-0" />
            Reload Launcher
        </button>


        <!-- Reset Apps: force-closes hung presentation apps without requiring edit mode.
            Essential recovery tool for presenters stuck on stage with a frozen app. -->
        <button
            type="button"
            onclick={handle_reset_apps}
            class="btn btn-sm preset-tonal-error hover:preset-filled-error-500 w-34 max-w-1/2 text-xs transition-all"
            title="Close all presentation apps (PowerPoint, Keynote, Adobe Acrobat, VLC). Use this if a presentation is frozen or stuck.">
            <XCircle size="0.85em" class="shrink-0" />
            {reset_apps_status || 'Reset Apps'}
        </button>
    </div>

    <div class="w-full flex flex-row flex-wrap items-center justify-center gap-0.5">
        <!-- Font size cycler: default → larger → smaller → default -->
        <button
            type="button"
            onclick={() => {
                const mode = $ae_loc.font_size_mode;
                if (!mode || mode === 'default') {
                    $ae_loc.font_size_mode = 'larger';
                } else if (mode === 'larger') {
                    $ae_loc.font_size_mode = 'smaller';
                } else {
                    $ae_loc.font_size_mode = 'default';
                }
            }}
            class="btn btn-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 group min-w-32 max-w-1/2 text-xs transition-all"
            title="Cycle font size (default → larger → smaller). Current: {$ae_loc.font_size_mode ??
                'default'}">
            {#if !$ae_loc.font_size_mode || $ae_loc.font_size_mode === 'default'}
                <span class="m-1 font-mono text-sm leading-none font-bold">A</span>
                <span class="hidden text-xs group-hover:inline-block">Font: Normal</span>
            {:else if $ae_loc.font_size_mode === 'larger'}
                <span class="m-1 font-mono text-base leading-none font-bold">A+</span>
                <span class="hidden text-xs group-hover:inline-block">Font: Larger</span>
            {:else}
                <span class="m-1 font-mono text-xs leading-none font-bold">A−</span>
                <span class="hidden text-xs group-hover:inline-block">Font: Smaller</span>
            {/if}
        </button>

        <!-- Light/dark mode toggle. DOM sync handled by +layout.svelte $effect on theme_mode. -->
        <button
            type="button"
            onclick={() => {
                $ae_loc.theme_mode = $ae_loc.theme_mode === 'dark' ? 'light' : 'dark';
            }}
            class="btn btn-sm preset-tonal-tertiary hover:preset-filled-tertiary-500 group min-w-32 max-w-1/2 text-xs transition-all"
            title="Toggle light/dark display mode. Current: {$ae_loc.theme_mode ?? 'light'}">
            {#if $ae_loc.theme_mode === 'dark'}
                <Moon class="m-1 inline-block" size="1em" />
                <span class="hidden group-hover:inline-block">Dark Mode</span>
            {:else}
                <Sun class="m-1 inline-block" size="1em" />
                <span class="hidden group-hover:inline-block">Light Mode</span>
            {/if}
        </button>
    </div>
</div>
