<script lang="ts">
import { untrack } from 'svelte';
interface Props {
    /** @type {import('./$types').PageData} */
    data: any;
}

let { data }: Props = $props();
let log_lvl: number = $state(0);

// Imports
import {
    Archive,
    Barcode,
    FileText,
    Info,
    LoaderCircle,
    Upload,
    X,
} from '@lucide/svelte';
import { Modal } from 'flowbite-svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { liveQuery } from 'dexie';
import { db_events } from '$lib/ae_events/db_events';
import { ae_snip, ae_loc, ae_api, slct } from '$lib/stores/ae_stores';
import {
    events_sess,
    events_slct
} from '$lib/stores/ae_events_stores';
import { pres_mgmt_loc } from '$lib/stores/ae_events_stores__pres_mgmt.svelte';
import { events_auth_loc } from '$lib/stores/ae_events_stores__auth.svelte';
import { events_func } from '$lib/ae_events/ae_events_functions';

import Session_view from './ae_comp__session_view.svelte';
import Session_page_menu from './ae_comp__session_page_menu.svelte';
import Comp_event_presentation_obj_li from '../../../../ae_comp__event_presentation_obj_li.svelte';
import Comp_event_presenter_form_agree from '../../presenter/[presenter_id]/ae_comp__event_presenter_form_agree.svelte';
import Comp_event_files_upload from '../../../../ae_comp__event_files_upload.svelte';
import Element_manage_event_file_li_wrap from '$lib/elements/element_manage_event_file_li_direct.svelte';
// STABILITY FIX: Capture URL params reactively via $derived so liveQuery
// closures see a stable identifier that updates on same-route navigation.
let url_session_id = $derived(data.params.session_id);
let url_event_id = $derived(data.params.event_id);

// KNOWN ISSUE (TODO): This page currently depends on related records
// (presentations, hosted files, presenters) already existing in IndexedDB.
// On a cold start (empty IDB) the dependent LQs may not re-run in the
// expected order and the UI can require manual refreshes. Do NOT copy
// this pattern for critical views until the refactor is implemented.

// Sync stores in the background
let ae_acct = $derived(data[data.account_id]);
$effect(() => {
    if (!ae_acct) return;
    untrack(() => {
        $ae_loc.url_origin = data.url.origin;
        $events_slct.event_id = url_event_id;
        $events_slct.event_session_id = url_session_id;
    });
});

// 1. Session Observable
let lq__event_session_obj = $derived(
    liveQuery(async () => {
        if (log_lvl) console.log(`[LQ] Querying Session: ${url_session_id}`);
        return await db_events.session.get(url_session_id);
    })
);

// 2. Presentation List Observable
// WHY: tmp_sort_2 encodes priority DESC → sort ASC → start_datetime ASC → code ASC → name ASC
// as a lexicographically correct string. See process_ae_obj__event_presentation_props.
let lq__event_presentation_obj_li = $derived(
    liveQuery(async () => {
        if (log_lvl)
            console.log(
                `[LQ] Querying Presentations for Session: ${url_session_id}`
            );
        return await db_events.presentation
            .where('event_session_id')
            .equals(url_session_id)
            .sortBy('tmp_sort_2');
    })
);

// 3. Other Observables
let lq__event_obj = $derived(
    liveQuery(async () => await db_events.event.get(url_event_id))
);

// Sync server-side pres_mgmt config into local PersistedState.
// WHY: this page is often reached directly by URL without first visiting the
// pres_mgmt overview, which is the only other place this sync runs. Without
// it, pres_mgmt_loc.current keeps stale values (e.g. hide__session_poc=true)
// that make POC assignment and other edit controls invisible to staff.
$effect(() => {
    const remote_cfg = $lq__event_obj?.mod_pres_mgmt_json;
    if (remote_cfg) {
        untrack(() => {
            events_func.sync_config__event_pres_mgmt({
                pres_mgmt_cfg_remote: remote_cfg,
                log_lvl: 0
            });
        });
    }
});

// $derived.by: capture only the specific ID so that unrelated store changes
// don't needlessly recreate the liveQuery observable.
let lq__event_presenter_obj = $derived.by(() => {
    const id = $events_slct.event_presenter_id;
    return liveQuery(async () => {
        if (!id) return null;
        return await db_events.presenter.get(id);
    });
});

let lq__auth__event_presenter_obj = $derived.by(() => {
    const pid = events_auth_loc.current.auth__person?.presenter_id;
    return liveQuery(async () => {
        if (!pid) return null;
        return await db_events.presenter.get(pid);
    });
});

if (!$events_sess.pres_mgmt) $events_sess.pres_mgmt = {};
</script>

<svelte:head>
    <title>
        Session: {ae_util.shorten_string({
            string: $lq__event_session_obj?.name ?? 'Loading...',
            max_length: 12
        })} - Pres Mgmt
    </title>
</svelte:head>

<div
    class="ae_events_pres_mgmt_event_session mx-auto w-full max-w-7xl space-y-2">
    <!-- Pass observable STORES to child components (they use $) -->
    <Session_page_menu
        {data}
        {lq__event_session_obj}
        {lq__auth__event_presenter_obj} />

    <!-- Session Info / Files toggle — mirrors the same pattern on the Presenter page.
         WHY: Admins and session POCs need to upload/manage session-level files (e.g. agendas,
         handouts) separately from presenter files. The toggle was present for years and was
         inadvertently dropped during the V3 migration. -->
    <!-- {#if $ae_loc.authenticated_access} -->
        <header class="ae_module_header flex flex-col items-start justify-between gap-2 sm:flex-row">
            <button
                type="button"
                onclick={() => {
                    pres_mgmt_loc.current.show_content__session_view =
                        pres_mgmt_loc.current.show_content__session_view === 'manage_files'
                            ? null
                            : 'manage_files';
                }}
                disabled={!$ae_loc.authenticated_access}
                class:cursor-not-allowed={!$ae_loc.authenticated_access}
                class="btn btn-md"
                class:opacity-50={!$ae_loc.authenticated_access}
                class:preset-filled-secondary-500={pres_mgmt_loc.current.show_content__session_view === 'manage_files'}
                class:preset-filled-tertiary-500={pres_mgmt_loc.current.show_content__session_view !== 'manage_files'}
                title="Toggle between session info and session file management">
                {#if pres_mgmt_loc.current.show_content__session_view === 'manage_files'}
                    <Info size="1em" class="m-1" />
                    Session Info?
                {:else}
                    <Archive size="1em" class="m-1" />
                    Session Files?
                    <span
                        class="badge preset-tonal-success"
                        class:hidden={!$lq__event_session_obj?.file_count}>
                        <FileText size="1em" class="m-1" />
                        {$lq__event_session_obj?.file_count}×
                    </span>
                {/if}
            </button>

            <div class="flex flex-col gap-1 items-end justify-end">

                <h1 class="text-2xl leading-snug font-bold">
                    {$lq__event_session_obj?.name}
                </h1>
                {#if (!pres_mgmt_loc.current.hide__session_code)}
                    <span class="badge preset-tonal-surface text-xs"
                        title="Session Code: {$lq__event_session_obj?.code}"
                        >
                        <Barcode size="1em" class="text-surface-600-400" />
                        {$lq__event_session_obj?.code}
                    </span>
                {/if}
            </div>
        </header>
    <!-- {/if} -->

    {#if pres_mgmt_loc.current.show_content__session_view === 'manage_files' && $ae_loc.authenticated_access}
        <!-- Session Files Section -->
        <div>
            {#if $ae_loc.trusted_access || events_auth_loc.current.auth__kv.session[url_session_id]}
                <Comp_event_files_upload
                    class_li="border border-surface-200-800 rounded-xl p-4 bg-surface-50-900 hover:bg-surface-100-900 transition-colors duration-200"
                    link_to_type="event_session"
                    link_to_id={url_session_id}>
                    {#snippet label()}
                        <span>
                            <div class="text-lg">
                                <Upload size="1em" />
                                <strong>Upload session files</strong>
                            </div>
                            <div class="text-sm italic opacity-60">
                                Session-level handouts, agendas, or supplemental materials
                            </div>
                        </span>
                    {/snippet}
                </Comp_event_files_upload>
            {/if}

            <div class="w-max max-w-full overflow-x-auto">
                <Element_manage_event_file_li_wrap
                    link_to_type="event_session"
                    link_to_id={url_session_id}
                    allow_basic={$ae_loc.trusted_access ||
                        !!events_auth_loc.current.auth__kv.session[url_session_id]}
                    allow_moderator={$ae_loc.trusted_access ||
                        !!events_auth_loc.current.auth__kv.session[url_session_id]}
                    container_class_li={''} />
            </div>
        </div>
    {:else}
        <!-- Metadata Section: Session identity card — name, time, room, host, description -->
        <div
            class="">
            <Session_view
                {lq__event_presenter_obj}
                {lq__event_session_obj}
                {lq__auth__event_presenter_obj}
                {lq__event_presentation_obj_li} />
        </div>

        <!-- Presentation List Section -->
        <div class="w-full" class:hidden={!$lq__event_presentation_obj_li?.length}>
            <!--
                CRITICAL FIX: Use the pre-loaded data (data.initial_session_obj) as a fallback
                until the `liveQuery` store ($lq...) emits its first value. This avoids
                a blank first-draw when IndexedDB is empty on a cold start — the LQ
                will take over once the DB write completes. Prefer blocking loads
                where possible; use this fallback when you must load asynchronously.
            -->
            <Comp_event_presentation_obj_li
                lq__event_presentation_obj_li={$lq__event_presentation_obj_li ??
                    data.initial_session_obj?.event_presentation_li ??
                    []}
                {log_lvl} />
        </div>

        <button
            type="button"
            onclick={() => {
                pres_mgmt_loc.current.show_content__session_view =
                    pres_mgmt_loc.current.show_content__session_view === 'manage_files'
                        ? null
                        : 'manage_files';
            }}
            class="btn btn-md"
            class:preset-filled-secondary-500={pres_mgmt_loc.current.show_content__session_view === 'manage_files'}
            class:preset-filled-tertiary-500={pres_mgmt_loc.current.show_content__session_view !== 'manage_files'}
            class:hidden={$lq__event_presentation_obj_li?.length}
            title="Toggle between session info and session file management">

                <Archive size="1em" class="m-1" />
                Session Files?
                <span
                    class="badge preset-tonal-success"
                    class:hidden={!$lq__event_session_obj?.file_count}>
                    <FileText size="1em" class="m-1" />
                    {$lq__event_session_obj?.file_count}×
                </span>

        </button>
    {/if}

    <!-- Background Connection Status (Non-blocking) -->
    {#if !$lq__event_session_obj}
        <div
            class="text-surface-400 flex items-center justify-center gap-2 py-4 italic">
            <LoaderCircle size="1em" class="animate-spin" />
            <span>Synchronizing with session data...</span>
        </div>
    {/if}
</div>

<!-- Presenter agree modal (opened from the presenter list) -->
<Modal
    title="{$lq__event_presenter_obj?.full_name} — Presenter Agreement"
    bind:open={$events_sess.pres_mgmt.show_modal__presenter_agree}
    autoclose={false}
    placement="center"
    size="lg"

    >
    {@const FormAgreeComp = Comp_event_presenter_form_agree as any}
    <FormAgreeComp {lq__event_presenter_obj} />
    {#snippet footer()}
        <div class="w-full text-center">
            <button
                type="button"
                onclick={() => ($events_sess.pres_mgmt.show_modal__presenter_agree = false)}
                class="btn preset-tonal-warning border border-warning-500">
                <X size="1em" class="mr-1" />
                Close
            </button>
        </div>
    {/snippet}
</Modal>
