<script lang="ts">
import { untrack } from 'svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { load_jitsi_report } from '$lib/ae_reports/reports_functions';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { idaa_loc } from '$lib/stores/ae_idaa_stores';
import JitsiUrlBuilder from './ae_idaa_comp__jitsi_url_builder.svelte';

interface MeetingEvent {
    timestamp: string;
    action: string;
    details: { full_name?: string };
}

interface MeetingParticipant {
    displayName: string;
    role: string;
}

interface MeetingReport {
    meeting_id: string;
    room_name: string;
    start_time: string;
    final_duration: string;
    final_participant_count: number;
    final_participants: MeetingParticipant[];
    events: MeetingEvent[];
}

// Extends MeetingReport with exclusion-applied participant data
interface MeetingReportEnriched extends MeetingReport {
    real_participants: MeetingParticipant[];
    real_participant_count: number;
}

// --- Data state ---
let meetings_all = $state<MeetingReport[]>([]);
let meetings_loading = $state(true);
let meetings_error = $state<string | null>(null);
let meetings_load_started = $state(false);

$effect(() => {
    if (meetings_load_started) return;
    if (!$idaa_loc.novi_verified && !$ae_loc.trusted_access) return;

    const api_cfg = $ae_api;
    const account_id = $ae_loc.account_id;
    if (!api_cfg || !account_id) return;

    meetings_load_started = true;
    meetings_loading = true;
    meetings_error = null;

    untrack(() => {
        void load_jitsi_report({
            api_cfg,
            account_id,
            log_lvl: 1
        })
            .then((m: MeetingReport[]) => {
                meetings_all = m ?? [];
                meetings_loading = false;
            })
            .catch((err: unknown) => {
                meetings_error =
                    err instanceof Error ? err.message : String(err);
                meetings_loading = false;
            });
    });
});

// --- Staff/test exclusion ---
// Read display names to exclude from site_cfg_json.jitsi_exclude_names.
// Matched case-insensitively against MeetingParticipant.displayName.
let exclude_names = $derived<string[]>(
    (($ae_loc.site_cfg_json as Record<string, unknown>)
        ?.jitsi_exclude_names as string[] | undefined)
        ?.map((n) => n.toLowerCase().trim()) ?? []
);

// Apply exclusion to every meeting — produces the "real" participant list
// used by all downstream filters, stats, and display.
let meetings_enriched = $derived<MeetingReportEnriched[]>(
    meetings_all.map((m) => {
        // final_participants can be null/undefined if meta_json.participants was null in the API response
        const all_participants: MeetingParticipant[] = m.final_participants ?? [];
        const real_participants =
            exclude_names.length > 0
                ? all_participants.filter(
                      (p) =>
                          !exclude_names.includes(
                              p.displayName.toLowerCase().trim()
                          )
                  )
                : all_participants;
        return {
            ...m,
            real_participants,
            real_participant_count: real_participants.length
        };
    })
);

// --- View mode ---
let group_by_room = $state(true);

// --- Filter state ---
let filter_real_only = $state(false);
let filter_min_participants = $state(0);
let filter_room_name = $state('');
let filter_date_from = $state('');
let filter_date_to = $state('');

let filters_are_modified = $derived(
    filter_real_only ||
        filter_min_participants !== 0 ||
        filter_room_name !== '' ||
        filter_date_from !== '' ||
        filter_date_to !== ''
);

function reset_filters() {
    filter_real_only = false;
    filter_min_participants = 0;
    filter_room_name = '';
    filter_date_from = '';
    filter_date_to = '';
}

// --- Duration helpers ---
function parse_duration_seconds(d: string): number {
    if (!d) return 0;
    const parts = d.split(':').map(Number);
    return (parts[0] ?? 0) * 3600 + (parts[1] ?? 0) * 60 + (parts[2] ?? 0);
}

function format_seconds(total: number): string {
    const h = Math.floor(total / 3600).toString().padStart(2, '0');
    const m = Math.floor((total % 3600) / 60).toString().padStart(2, '0');
    const s = Math.floor(total % 60).toString().padStart(2, '0');
    return `${h}:${m}:${s}`;
}

function compute_end_time(start_time: string, duration: string): string {
    if (!start_time || !duration) return '—';
    const start = new Date(start_time);
    const secs = parse_duration_seconds(duration);
    if (secs === 0) return '—';
    const end = new Date(start.getTime() + secs * 1000);
    return end.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}

// --- Derived: filtered meetings ---
// All counts and thresholds use real_participant_count (post-exclusion).
let meetings_filtered = $derived.by(() => {
    return meetings_enriched.filter((m) => {
        if (filter_real_only) {
            const dur_secs = parse_duration_seconds(m.final_duration);
            if (m.real_participant_count < 2 && dur_secs <= 300) return false;
        }
        if (m.real_participant_count < filter_min_participants) return false;
        if (
            filter_room_name &&
            !m.room_name?.toLowerCase().includes(filter_room_name.toLowerCase())
        )
            return false;
        if (filter_date_from) {
            if (Date.parse(m.start_time) < Date.parse(filter_date_from))
                return false;
        }
        if (filter_date_to) {
            if (
                Date.parse(m.start_time) >
                Date.parse(filter_date_to + 'T23:59:59.999')
            )
                return false;
        }
        return true;
    });
});

// --- Derived: grouped by room ---
// Rooms sorted by most-recent session desc; sessions within each room sorted asc.
let meetings_grouped = $derived.by<Map<string, MeetingReportEnriched[]>>(() => {
    const groups = new Map<string, MeetingReportEnriched[]>();
    for (const m of meetings_filtered) {
        const room = m.room_name ?? 'Unknown';
        if (!groups.has(room)) groups.set(room, []);
        groups.get(room)!.push(m);
    }
    for (const sessions of groups.values()) {
        sessions.sort(
            (a, b) =>
                new Date(a.start_time).getTime() -
                new Date(b.start_time).getTime()
        );
    }
    return new Map(
        [...groups.entries()].sort((a, b) => {
            const a_last = a[1].at(-1)?.start_time ?? '';
            const b_last = b[1].at(-1)?.start_time ?? '';
            return new Date(b_last).getTime() - new Date(a_last).getTime();
        })
    );
});

// --- Summary stats ---
let summary = $derived.by(() => {
    const count = meetings_filtered.length;
    const total_participants = meetings_filtered.reduce(
        (sum, m) => sum + m.real_participant_count,
        0
    );
    const total_secs = meetings_filtered.reduce(
        (sum, m) => sum + parse_duration_seconds(m.final_duration),
        0
    );
    const avg_secs = count > 0 ? Math.round(total_secs / count) : 0;
    return {
        count,
        total_participants,
        avg_duration: format_seconds(avg_secs),
        total_duration: format_seconds(total_secs)
    };
});

function room_stats(sessions: MeetingReportEnriched[]) {
    const total_secs = sessions.reduce(
        (sum, m) => sum + parse_duration_seconds(m.final_duration),
        0
    );
    const unique_names = new Set(
        sessions.flatMap((m) => m.real_participants.map((p) => p.displayName))
    );
    return {
        meeting_count: sessions.length,
        total_duration: format_seconds(total_secs),
        unique_participant_count: unique_names.size
    };
}

// --- Accordion / room open state ---
let open_accordions = $state<Record<string, boolean>>({});
// Rooms default to open; only track explicitly-closed rooms.
let closed_rooms = $state<Record<string, boolean>>({});

function toggle_accordion(meeting_id: string) {
    open_accordions[meeting_id] = !open_accordions[meeting_id];
}

function toggle_room(room_name: string) {
    closed_rooms[room_name] = !closed_rooms[room_name];
}

function is_room_open(room_name: string): boolean {
    return !closed_rooms[room_name];
}

// --- URL Builder ---
let show_url_builder = $state(false);

// --- Export ---
function download_file(content: string, filename: string, mime: string) {
    const blob = new Blob([content], { type: mime });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

function export_csv() {
    const rows: string[][] = [
        [
            'Meeting ID',
            'Room Name',
            'Start Time',
            'Duration',
            'Participant Count',
            'Participants'
        ]
    ];
    for (const m of meetings_filtered) {
        rows.push([
            m.meeting_id ?? '',
            m.room_name ?? '',
            m.start_time ? new Date(m.start_time).toISOString() : '',
            m.final_duration ?? '',
            String(m.real_participant_count),
            m.real_participants.map((p) => p.displayName).join('; ')
        ]);
    }
    const csv = rows
        .map((r) =>
            r.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(',')
        )
        .join('\n');
    download_file(csv, 'jitsi_meeting_report.csv', 'text/csv;charset=utf-8;');
}

function export_json() {
    download_file(
        JSON.stringify(
            meetings_filtered.map((m) => ({
                ...m,
                final_participants: m.real_participants,
                final_participant_count: m.real_participant_count
            })),
            null,
            2
        ),
        'jitsi_meeting_report.json',
        'application/json'
    );
}
</script>

<svelte:head>
    <title>&AElig;: Jitsi Meeting Reports</title>
</svelte:head>

<div class="w-full max-w-5xl space-y-4 p-4">
    <!-- Page header: view toggle + export buttons -->
    <div class="flex flex-row flex-wrap items-center justify-between gap-2">
        <h1 class="text-xl font-bold">Jitsi Meeting Reports</h1>
        <div class="flex items-center gap-2">
            <!-- View mode toggle -->
            <div class="border-surface-200-800 flex overflow-hidden rounded-lg border text-sm">
                <button
                    type="button"
                    onclick={() => (group_by_room = true)}
                    title="Group sessions by room"
                    class="flex items-center gap-1.5 px-3 py-1.5 font-medium transition-colors duration-150 {group_by_room
                        ? 'preset-filled-primary'
                        : 'opacity-60 hover:opacity-90 hover:bg-surface-100-900'}">
                    <span class="fas fa-layer-group text-xs" aria-hidden="true"></span>
                    <span class="hidden sm:inline">By Room</span>
                </button>
                <button
                    type="button"
                    onclick={() => (group_by_room = false)}
                    title="Show all sessions as a flat list"
                    class="border-surface-200-800 flex items-center gap-1.5 border-l px-3 py-1.5 font-medium transition-colors duration-150 {!group_by_room
                        ? 'preset-filled-primary'
                        : 'opacity-60 hover:opacity-90 hover:bg-surface-100-900'}">
                    <span class="fas fa-list text-xs" aria-hidden="true"></span>
                    <span class="hidden sm:inline">Flat List</span>
                </button>
            </div>
            <button
                type="button"
                onclick={export_csv}
                disabled={meetings_filtered.length === 0}
                title="Export filtered meetings as CSV"
                class="btn btn-sm preset-tonal-primary disabled:opacity-40">
                <span class="fas fa-file-csv" aria-hidden="true"></span>
                <span class="ml-1 hidden sm:inline">CSV</span>
            </button>
            <button
                type="button"
                onclick={export_json}
                disabled={meetings_filtered.length === 0}
                title="Export filtered meetings as JSON"
                class="btn btn-sm preset-tonal-surface border-surface-200-800 border disabled:opacity-40">
                <span class="fas fa-file-code" aria-hidden="true"></span>
                <span class="ml-1 hidden sm:inline">JSON</span>
            </button>
        </div>
    </div>

    <!-- Jitsi URL Builder — trusted_access only -->
    {#if $ae_loc.trusted_access}
        <div
            class="bg-surface-100-900 border-surface-200-800 overflow-hidden rounded-xl border">
            <button
                type="button"
                onclick={() => (show_url_builder = !show_url_builder)}
                class="hover:bg-surface-200-800 flex w-full items-center justify-between gap-2 p-3 text-left transition-colors duration-200">
                <span class="flex items-center gap-2 text-sm font-semibold">
                    <span class="fas fa-tools" aria-hidden="true"></span>
                    Jitsi URL Builder
                </span>
                <span
                    class="fas text-xs opacity-60"
                    class:fa-chevron-down={!show_url_builder}
                    class:fa-chevron-up={show_url_builder}
                    aria-hidden="true"></span>
            </button>
            {#if show_url_builder}
                <div class="border-surface-200-800 border-t p-4">
                    <JitsiUrlBuilder />
                </div>
            {/if}
        </div>
    {/if}

    <!-- Filter bar -->
    <div
        class="bg-surface-100-900 border-surface-200-800 flex flex-row flex-wrap items-end gap-3 rounded-xl border p-3">
        <!-- Real meetings only toggle -->
        <label class="flex cursor-pointer items-center gap-2 self-end pb-1.5">
            <input
                type="checkbox"
                bind:checked={filter_real_only}
                class="checkbox checkbox-sm" />
            <span class="text-sm font-medium whitespace-nowrap"
                >Real meetings only</span>
        </label>
        <div class="bg-surface-200-800 hidden h-8 w-px self-end sm:block"></div>
        <div>
            <label
                for="filter_min_p"
                class="mb-1 block text-xs tracking-wide uppercase opacity-40">
                Min. Participants
            </label>
            <input
                type="number"
                id="filter_min_p"
                min="0"
                bind:value={filter_min_participants}
                class="border-surface-200-800 bg-surface-50-950 w-20 rounded border px-2 py-1" />
        </div>
        <div>
            <label
                for="filter_room"
                class="mb-1 block text-xs tracking-wide uppercase opacity-40">
                Room Name
            </label>
            <input
                type="text"
                id="filter_room"
                placeholder="Search rooms..."
                bind:value={filter_room_name}
                class="border-surface-200-800 bg-surface-50-950 rounded border px-2 py-1" />
        </div>
        <div>
            <label
                for="filter_date_from"
                class="mb-1 block text-xs tracking-wide uppercase opacity-40">
                From
            </label>
            <input
                type="date"
                id="filter_date_from"
                bind:value={filter_date_from}
                class="border-surface-200-800 bg-surface-50-950 rounded border px-2 py-1" />
        </div>
        <div>
            <label
                for="filter_date_to"
                class="mb-1 block text-xs tracking-wide uppercase opacity-40">
                To
            </label>
            <input
                type="date"
                id="filter_date_to"
                bind:value={filter_date_to}
                class="border-surface-200-800 bg-surface-50-950 rounded border px-2 py-1" />
        </div>
        {#if filters_are_modified}
            <button
                type="button"
                onclick={reset_filters}
                class="btn btn-sm preset-tonal-surface border-surface-200-800 self-end border"
                title="Reset all filters to defaults">
                <span class="fas fa-times" aria-hidden="true"></span>
                Reset
            </button>
        {/if}
    </div>

    {#if meetings_loading}
        <!-- Loading skeleton -->
        <div
            class="animate-pulse space-y-2"
            role="status"
            aria-live="polite"
            aria-label="Loading meeting reports">
            {#each [1, 2, 3, 4] as _, i (i)}
                <div class="bg-surface-200-800 h-14 w-full rounded-xl"></div>
            {/each}
        </div>
    {:else if meetings_error}
        <!-- Error state -->
        <div class="bg-error-100 border-error-300 rounded-xl border p-4">
            <div class="font-bold">Error Loading Reports</div>
            <p class="mt-1">
                An error occurred while fetching the meeting reports:
            </p>
            <pre
                class="mt-2 overflow-auto text-xs whitespace-pre-wrap">{meetings_error}</pre>
        </div>
    {:else}
        <!-- Summary stats -->
        {#if meetings_all.length > 0}
            <div class="grid grid-cols-2 gap-2 sm:grid-cols-4">
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-3 text-center">
                    <div class="text-2xl font-bold">{summary.count}</div>
                    <div class="text-xs tracking-wide uppercase opacity-40">
                        Meetings Shown
                    </div>
                </div>
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-3 text-center">
                    <div class="text-2xl font-bold">
                        {summary.total_participants}
                    </div>
                    <div class="text-xs tracking-wide uppercase opacity-40">
                        Total Participants
                    </div>
                </div>
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-3 text-center">
                    <div class="font-mono text-2xl font-bold">
                        {summary.avg_duration}
                    </div>
                    <div class="text-xs tracking-wide uppercase opacity-40">
                        Avg Duration
                    </div>
                </div>
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-3 text-center">
                    <div class="font-mono text-2xl font-bold">
                        {summary.total_duration}
                    </div>
                    <div class="text-xs tracking-wide uppercase opacity-40">
                        Total Duration
                    </div>
                </div>
            </div>
        {/if}

        <!-- ═══════════════════════════════════════════════════════════
             GROUPED BY ROOM VIEW
             ═══════════════════════════════════════════════════════════ -->
        {#if group_by_room}
            {#if meetings_grouped.size > 0}
                <div class="space-y-2">
                    {#each meetings_grouped as [room_name, sessions] (room_name)}
                        {@const stats = room_stats(sessions)}
                        <div
                            class="bg-surface-50-900 border-surface-200-800 overflow-hidden rounded-xl border">
                            <!-- Room header -->
                            <button
                                type="button"
                                onclick={() => toggle_room(room_name)}
                                class="hover:bg-surface-100-900 flex w-full items-center justify-between gap-2 p-3 text-left transition-colors duration-200">
                                <div class="min-w-0 flex-1">
                                    <div class="truncate font-semibold">
                                        {room_name}
                                    </div>
                                    <div
                                        class="mt-0.5 flex flex-wrap gap-3 text-xs opacity-60">
                                        <span>
                                            <span
                                                class="fas fa-calendar-alt mr-1"
                                                aria-hidden="true"></span>
                                            {stats.meeting_count}
                                            {stats.meeting_count === 1
                                                ? 'session'
                                                : 'sessions'}
                                        </span>
                                        <span>
                                            <span
                                                class="fas fa-users mr-1"
                                                aria-hidden="true"></span>
                                            {stats.unique_participant_count} unique
                                            {stats.unique_participant_count === 1
                                                ? 'participant'
                                                : 'participants'}
                                        </span>
                                        <span class="font-mono">
                                            <span
                                                class="fas fa-clock mr-1"
                                                aria-hidden="true"></span>
                                            {stats.total_duration} total
                                        </span>
                                    </div>
                                </div>
                                <span
                                    class="fas flex-none pl-2 text-xs opacity-60"
                                    class:fa-chevron-down={is_room_open(
                                        room_name
                                    )}
                                    class:fa-chevron-up={!is_room_open(
                                        room_name
                                    )}
                                    aria-hidden="true"></span>
                            </button>

                            <!-- Room session table -->
                            {#if is_room_open(room_name)}
                                <div
                                    class="border-surface-200-800 overflow-x-auto border-t">
                                    <table class="w-full text-sm">
                                        <thead>
                                            <tr
                                                class="bg-surface-100-900 border-surface-200-800 border-b">
                                                <th
                                                    class="px-3 py-2 text-left font-medium whitespace-nowrap opacity-60"
                                                    >Date</th>
                                                <th
                                                    class="px-3 py-2 text-left font-medium whitespace-nowrap opacity-60"
                                                    >Start</th>
                                                <th
                                                    class="px-3 py-2 text-left font-medium whitespace-nowrap opacity-60"
                                                    >End</th>
                                                <th
                                                    class="px-3 py-2 text-left font-medium whitespace-nowrap opacity-60"
                                                    >Duration</th>
                                                <th
                                                    class="px-3 py-2 text-center font-medium whitespace-nowrap opacity-60"
                                                    title="Participant count (after staff exclusion)">#</th>
                                                <th
                                                    class="px-3 py-2 text-left font-medium opacity-60"
                                                    >Participants</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {#each sessions as m (m.meeting_id)}
                                                {@const mods = m.real_participants.filter((p) => p.role === 'moderator')}
                                                {@const others = m.real_participants.filter((p) => p.role !== 'moderator')}
                                                {@const all_names = m.real_participants.map((p) => `${p.displayName} (${p.role})`).join('\n')}
                                                <tr
                                                    class="border-surface-200-800 hover:bg-surface-100-900 border-b transition-colors duration-200">
                                                    <td
                                                        class="px-3 py-2 whitespace-nowrap">
                                                        {new Date(
                                                            m.start_time
                                                        ).toLocaleDateString()}
                                                    </td>
                                                    <td
                                                        class="px-3 py-2 whitespace-nowrap">
                                                        {new Date(
                                                            m.start_time
                                                        ).toLocaleTimeString(
                                                            [],
                                                            {
                                                                hour: '2-digit',
                                                                minute: '2-digit'
                                                            }
                                                        )}
                                                    </td>
                                                    <td
                                                        class="px-3 py-2 whitespace-nowrap">
                                                        {compute_end_time(m.start_time, m.final_duration)}
                                                    </td>
                                                    <td
                                                        class="px-3 py-2 font-mono whitespace-nowrap">
                                                        {m.final_duration}
                                                    </td>
                                                    <td
                                                        class="px-3 py-2 text-center"
                                                        title={all_names || 'No participants'}>
                                                        {m.real_participant_count}
                                                    </td>
                                                    <td class="px-3 py-2" title={all_names || 'No participants'}>
                                                        {#if m.real_participant_count === 0}
                                                            <span class="opacity-40">—</span>
                                                        {:else}
                                                            <div class="space-y-0.5 text-xs">
                                                                {#if mods.length > 0}
                                                                    <div>
                                                                        <span class="mr-1 opacity-40">Mod:</span>
                                                                        <span class="font-semibold">{mods.map((p) => p.displayName).join(', ')}</span>
                                                                    </div>
                                                                {/if}
                                                                {#if others.length > 0}
                                                                    <div class="opacity-80">
                                                                        {others.slice(0, 5).map((p) => p.displayName).join(', ')}{others.length > 5 ? ` +${others.length - 5} more` : ''}
                                                                    </div>
                                                                {/if}
                                                            </div>
                                                        {/if}
                                                    </td>
                                                </tr>
                                            {/each}
                                        </tbody>
                                    </table>
                                </div>
                            {/if}
                        </div>
                    {/each}
                </div>
            {:else}
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-6 text-center">
                    {#if meetings_all.length > 0}
                        <div class="font-semibold">
                            No meetings match the current filters
                        </div>
                        <p class="mt-1 text-sm opacity-60">
                            Try adjusting the filters or clearing the date
                            range.
                        </p>
                        <button
                            type="button"
                            onclick={reset_filters}
                            class="btn btn-sm preset-tonal-surface border-surface-200-800 mt-3 border">
                            <span class="fas fa-times mr-1" aria-hidden="true"
                            ></span>
                            Reset Filters
                        </button>
                    {:else}
                        <div class="font-semibold">No Meeting Reports Found</div>
                        <p class="mt-1 text-sm opacity-60">
                            There are no Jitsi activity logs to display.
                        </p>
                    {/if}
                </div>
            {/if}

        <!-- ═══════════════════════════════════════════════════════════
             FLAT LIST VIEW
             ═══════════════════════════════════════════════════════════ -->
        {:else}
            {#if meetings_filtered.length > 0}
                <div class="space-y-2">
                    {#each meetings_filtered as meeting (meeting.meeting_id)}
                        <div
                            class="bg-surface-50-900 border-surface-200-800 overflow-hidden rounded-xl border">
                            <!-- Accordion header -->
                            <!-- svelte-ignore a11y_click_events_have_key_events -->
                            <!-- svelte-ignore a11y_no_static_element_interactions -->
                            <div
                                class="hover:bg-surface-100-900 cursor-pointer p-3 transition-colors duration-200"
                                onclick={() =>
                                    toggle_accordion(meeting.meeting_id)}>
                                <div class="flex items-center gap-2">
                                    <div class="min-w-0 flex-1">
                                        <div class="truncate font-semibold">
                                            {meeting.room_name}
                                        </div>
                                        <div class="text-sm opacity-60">
                                            {new Date(meeting.start_time).toLocaleString()}
                                            {#if meeting.final_duration && meeting.final_duration !== '00:00:00'}
                                                <span class="mx-1 opacity-50">→</span>{compute_end_time(meeting.start_time, meeting.final_duration)}
                                            {/if}
                                        </div>
                                    </div>
                                    <div
                                        class="hidden flex-none items-center gap-4 text-sm opacity-60 sm:flex">
                                        <span title="Duration">
                                            <span
                                                class="fas fa-clock mr-1"
                                                aria-hidden="true"></span>
                                            {meeting.final_duration}
                                        </span>
                                        <span title="Participant count">
                                            <span
                                                class="fas fa-users mr-1"
                                                aria-hidden="true"></span>
                                            {meeting.real_participant_count}
                                        </span>
                                    </div>
                                    <div class="flex-none pl-2">
                                        <span
                                            class="fas inline-block transition-transform duration-200"
                                            class:fa-chevron-down={!open_accordions[
                                                meeting.meeting_id
                                            ]}
                                            class:fa-chevron-up={open_accordions[
                                                meeting.meeting_id
                                            ]}
                                            aria-hidden="true"></span>
                                    </div>
                                </div>
                                <!-- Mobile stats row -->
                                <div
                                    class="mt-1 flex gap-4 text-sm opacity-60 sm:hidden">
                                    <span>
                                        <span
                                            class="fas fa-clock mr-1"
                                            aria-hidden="true"></span>
                                        {meeting.final_duration}
                                    </span>
                                    <span>
                                        <span
                                            class="fas fa-users mr-1"
                                            aria-hidden="true"></span>
                                        {meeting.real_participant_count}
                                        {meeting.real_participant_count === 1
                                            ? 'participant'
                                            : 'participants'}
                                    </span>
                                </div>
                            </div>

                            <!-- Accordion body -->
                            {#if open_accordions[meeting.meeting_id]}
                                <div
                                    class="border-surface-200-800 grid grid-cols-1 gap-4 border-t p-4 md:grid-cols-2">
                                    <!-- Event Timeline -->
                                    <div>
                                        <div
                                            class="mb-2 text-xs tracking-wide uppercase opacity-40">
                                            Event Timeline
                                        </div>
                                        {#if meeting.events && meeting.events.length > 0}
                                            <ul class="space-y-1">
                                                {#each meeting.events as event, i (i)}
                                                    <li
                                                        class="flex items-start gap-2 text-sm">
                                                        <span
                                                            class="mt-0.5 font-mono text-xs whitespace-nowrap opacity-60">
                                                            [{new Date(
                                                                event.timestamp
                                                            ).toLocaleTimeString()}]
                                                        </span>
                                                        <span>
                                                            <span
                                                                class="font-semibold">
                                                                {ae_util.to_title_case(
                                                                    event.action.replace(
                                                                        'jitsi_meeting_',
                                                                        ''
                                                                    )
                                                                )}
                                                            </span>
                                                            {#if event.details?.full_name}
                                                                <span
                                                                    class="opacity-60">
                                                                    — {event
                                                                        .details
                                                                        .full_name}
                                                                </span>
                                                            {/if}
                                                        </span>
                                                    </li>
                                                {/each}
                                            </ul>
                                        {:else}
                                            <p class="text-sm italic opacity-60">
                                                No discrete events recorded.
                                            </p>
                                        {/if}
                                    </div>

                                    <!-- Final Participants (exclusion-applied) -->
                                    <div>
                                        <div
                                            class="mb-2 text-xs tracking-wide uppercase opacity-40">
                                            Final Participants ({meeting.real_participant_count})
                                        </div>
                                        {#if meeting.real_participants && meeting.real_participants.length > 0}
                                            <table class="w-full text-sm">
                                                <thead>
                                                    <tr
                                                        class="border-surface-200-800 border-b">
                                                        <th
                                                            class="py-1 text-left font-medium opacity-60"
                                                            >Name</th>
                                                        <th
                                                            class="py-1 text-left font-medium opacity-60"
                                                            >Role</th>
                                                    </tr>
                                                </thead>
                                                <tbody>
                                                    {#each meeting.real_participants as participant (participant.displayName)}
                                                        <tr
                                                            class="border-surface-200-800 hover:bg-surface-100-900 border-b transition-colors duration-200">
                                                            <td class="py-1"
                                                                >{participant.displayName}</td>
                                                            <td class="py-1"
                                                                >{ae_util.to_title_case(
                                                                    participant.role
                                                                )}</td>
                                                        </tr>
                                                    {/each}
                                                </tbody>
                                            </table>
                                        {:else}
                                            <p class="text-sm italic opacity-60">
                                                No participant data available.
                                            </p>
                                        {/if}
                                    </div>
                                </div>
                            {/if}
                        </div>
                    {/each}
                </div>
            {:else}
                <div
                    class="bg-surface-100-900 border-surface-200-800 rounded-xl border p-6 text-center">
                    {#if meetings_all.length > 0}
                        <div class="font-semibold">
                            No meetings match the current filters
                        </div>
                        <p class="mt-1 text-sm opacity-60">
                            Try lowering the minimum participants or clearing
                            the date range.
                        </p>
                        <button
                            type="button"
                            onclick={reset_filters}
                            class="btn btn-sm preset-tonal-surface border-surface-200-800 mt-3 border">
                            <span class="fas fa-times mr-1" aria-hidden="true"
                            ></span>
                            Reset Filters
                        </button>
                    {:else}
                        <div class="font-semibold">No Meeting Reports Found</div>
                        <p class="mt-1 text-sm opacity-60">
                            There are no Jitsi activity logs to display.
                        </p>
                    {/if}
                </div>
            {/if}
        {/if}
    {/if}
</div>
