<script lang="ts">
import { untrack } from 'svelte';
import { liveQuery } from 'dexie';
import { db_events } from '$lib/ae_events/db_events';
import { events_sess } from '$lib/stores/ae_events_stores';
import { leads_loc } from '$lib/stores/ae_events_stores__leads.svelte';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { page } from '$app/state';
import { events_func } from '$lib/ae_events/ae_events_functions';
import { ae_util } from '$lib/ae_utils/ae_utils';
import {
    CreditCard,
    Download,
    List as ListIcon,
    LoaderCircle,
    Plus,
    Settings
} from '@lucide/svelte';
import Comp_exhibit_tracking_search from './ae_comp__exhibit_tracking_search.svelte';
import Comp_exhibit_tracking_obj_li from './ae_comp__exhibit_tracking_obj_li.svelte';
import Tab_add from './ae_comp__tab_add.svelte';
import Tab_start from './ae_comp__tab_start.svelte';
import Tab_manage from './ae_comp__tab_manage.svelte';
import Comp_exhibit_payment from './ae_comp__exhibit_payment.svelte';

// leads_loc is a PersistedState store — defaults are always initialized.

// --- Sign-In State (Derived) ---
// 1. Manager Access (Bypass) OR 2. Valid Exhibit Auth entry
let is_signed_in = $derived(
    $ae_loc.manager_access ||
        !!leads_loc.current.auth_exhibit_kv?.[page.params.exhibit_id ?? '']
);

// --- Tab State (Sticky via Store) ---
let active_tab = $derived.by(() => {
    const exhibit_id = page.params.exhibit_id;
    if (!exhibit_id) return 'start';
    const saved_tab = leads_loc.current.tab?.[exhibit_id] ?? 'list';
    // If signed in but stuck on start tab, go to list
    if (is_signed_in && saved_tab === 'start') return 'list';
    // If payment tab was saved but payments are no longer required, fall back to list
    if (saved_tab === 'payment' && !leads_require_payment) return 'list';
    return saved_tab;
});
let previous_main_tab = $state('list'); // To remember if we were on 'add' or 'list' before going to 'manage'

function set_active_tab(new_tab: string) {
    const exhibit_id = page.params.exhibit_id;
    if (!exhibit_id) return;
    leads_loc.current.tab[exhibit_id] = new_tab;
}

let tracking_id_li: Array<string> = $state([]);
let search_debounce_timer: any = null;
let last_search_id = 0;
let last_executed_key = '';
let log_lvl = 0;

// --- NEW: Direct Reactive List Pattern ---
let raw_lead_li: any[] = $state([]);

// Final filtered list that the UI actually sees
// Applying the HARD GUARD here ensures that no matter where the data came from
// (API or IDB), it MUST match the selected licensee.
let filtered_lead_li = $derived.by(() => {
    const licensee_filter = search_params.licensee_email;
    const show_hidden = search_params.show_hidden;

    return raw_lead_li.filter((lead) => {
        // Never show disabled (removed) leads — enable=0/false means the exhibitor deleted them
        if (lead.enable === 0 || lead.enable === false) return false;
        // Exclude hidden leads unless show_hidden is toggled on
        if (!show_hidden && lead.hide) return false;
        if (licensee_filter === 'all') return true;
        const capturer = lead.external_person_id || lead.group;
        return capturer === licensee_filter;
    });
});

// Subscribe to the Lead List
$effect(() => {
    const ids = tracking_id_li;
    const exhibit_id = page.params.exhibit_id;
    const has_search = !!leads_loc.current.tracking__qry__search_text;

    const observable = liveQuery(async () => {
        // 1. Specific IDs provided (from API Search or Manual Entry)
        if (Array.isArray(ids) && ids.length > 0) {
            const results = await db_events.exhibit_tracking.bulkGet(ids);
            return results.filter((item) => item !== undefined);
        }

        // 2. Fallback broad search (Initial load or no search text)
        if (exhibit_id && !has_search) {
            return await db_events.exhibit_tracking
                .where('event_exhibit_id')
                .equals(exhibit_id)
                .reverse()
                .sortBy('created_on');
        }

        return [];
    });

    const subscription = observable.subscribe((res) => {
        raw_lead_li = res;
    });

    return () => subscription.unsubscribe();
});

// Exhibit Info
const lq__exhibit_obj = liveQuery(() => {
    const exhibit_id = page.params.exhibit_id;
    if (!exhibit_id) return undefined;
    return db_events.exhibit.get(exhibit_id);
});

// Event-level config — read mod_exhibits_json for payment visibility + Stripe keys.
// Configured via /events/[event_id]/leads/config (administrator only).
const lq__event_obj = liveQuery(() => {
    const event_id = page.params.event_id;
    if (!event_id) return undefined;
    return db_events.event.get(event_id);
});

// When false (default), all billing UI is hidden — set true when event uses Stripe payment.
let leads_require_payment = $derived(
    ($lq__event_obj?.mod_exhibits_json as any)?.leads_require_payment === true
);

// Stripe keys from mod_exhibits_json — passed to the payment component.
// The component falls back to site_cfg_json if these are null (legacy migration path).
let stripe_cfg = $derived({
    stripe_publishable_key: ($lq__event_obj?.mod_exhibits_json as any)?.stripe_publishable_key ?? null,
    stripe_btn_1_license:   ($lq__event_obj?.mod_exhibits_json as any)?.stripe_btn_1_license   ?? null,
    stripe_btn_3_license:   ($lq__event_obj?.mod_exhibits_json as any)?.stripe_btn_3_license   ?? null,
    stripe_btn_6_license:   ($lq__event_obj?.mod_exhibits_json as any)?.stripe_btn_6_license   ?? null,
    stripe_btn_10_license:  ($lq__event_obj?.mod_exhibits_json as any)?.stripe_btn_10_license  ?? null,
});

// Standardized Reactive Search Pattern
let search_params = $derived.by(() => {
    let licensee_email = leads_loc.current.tracking__qry__licensee_email;

    // 'my' is a legacy value — the search component now resolves to the real identity
    // on mount and migrates stale persisted values. This block is a silent fallback
    // for any session that still has 'my' before the component has had a chance to run.
    if (licensee_email === 'my') {
        const kv = leads_loc.current.auth_exhibit_kv?.[page.params.exhibit_id ?? ''];
        licensee_email = kv?.type === 'shared'
            ? 'shared_passcode'
            : kv?.key || 'all';
    }

    return {
        v: leads_loc.current.tracking__search_version,
        str: (leads_loc.current.tracking__qry__search_text ?? '')
            .toLowerCase()
            .trim(),
        sort: leads_loc.current.tracking__qry__sort_order,
        licensee_email: licensee_email,
        exhibit_id: page.params.exhibit_id,
        remote_first: leads_loc.current.tracking__qry__remote_first,
        show_hidden: leads_loc.current.show_hidden ?? false
    };
});

$effect(() => {
    const params = search_params;
    if (search_debounce_timer) clearTimeout(search_debounce_timer);
    search_debounce_timer = setTimeout(() => {
        untrack(() => {
            handle_search_refresh(params);
            // Reset countdown on manual search
            $events_sess.leads.next_refresh_countdown =
                leads_loc.current.refresh_interval_sec || 25;
        });
    }, 300);
    return () => {
        if (search_debounce_timer) clearTimeout(search_debounce_timer);
    };
});

// --- Auto-Refresh Timer Logic ---
$effect(() => {
    if (!is_signed_in) return;

    const interval = setInterval(() => {
        untrack(() => {
            if ($events_sess.leads.next_refresh_countdown > 0) {
                $events_sess.leads.next_refresh_countdown--;
            } else {
                // Trigger refresh
                leads_loc.current.tracking__search_version++;
                $events_sess.leads.next_refresh_countdown =
                    leads_loc.current.refresh_interval_sec || 25;
            }
        });
    }, 1000);

    return () => clearInterval(interval);
});

async function handle_search_refresh(params: any) {
    const qry_key = JSON.stringify(params);
    if (qry_key === last_executed_key) return;
    last_executed_key = qry_key;

    const current_search_id = ++last_search_id;
    const exhibit_id = params.exhibit_id;
    const remote_first = params.remote_first;

    if (!exhibit_id) return;

    if (log_lvl)
        console.log(
            `🔎 [Trace] Lead Search #${current_search_id}: START (remote=${remote_first}, exhibit=${exhibit_id}, str=${params.str})`
        );

    untrack(() => {
        $events_sess.leads.submit_status__search = 'searching';
    });

    const qry_str = params.str;

    // 1. FAST PATH: Local IDB Search
    if (!remote_first) {
        try {
            const target_exhibit_id = exhibit_id;
            const target_licensee_email = params.licensee_email;

            let local_results = await db_events.exhibit_tracking
                .where('event_exhibit_id')
                .equals(target_exhibit_id)
                .filter((tracking) => {
                    // 0. Never include disabled (removed) records — they're soft-deleted
                    if (!tracking.enable) return false;
                    // 1. Hide filter — exclude hidden records unless show_hidden is on
                    if (!params.show_hidden && tracking.hide) return false;

                    // 2. Licensee Email Filter
                    if (target_licensee_email !== 'all') {
                        if (
                            tracking.external_person_id !==
                            target_licensee_email
                        )
                            return false;
                    }

                    if (qry_str) {
                        const name = (
                            tracking.event_badge_full_name ?? ''
                        ).toLowerCase();
                        const email = (
                            tracking.event_badge_email ?? ''
                        ).toLowerCase();
                        const notes = ae_util
                            .strip_html(tracking.exhibitor_notes ?? '')
                            .toLowerCase();
                        // Guard: Prevent "undefined" from being searched
                        if (tracking.exhibitor_notes === 'undefined') {
                            tracking.exhibitor_notes = '';
                        }
                        const qry_string = (
                            tracking.default_qry_str ?? ''
                        ).toLowerCase();

                        if (
                            !name.includes(qry_str) &&
                            !email.includes(qry_str) &&
                            !notes.includes(qry_str) &&
                            !qry_string.includes(qry_str)
                        )
                            return false;
                    }
                    return true;
                })
                .toArray();

            local_results.sort((a, b) => {
                switch (params.sort) {
                    case 'name_asc':
                        return (a.event_badge_full_name ?? '').localeCompare(
                            b.event_badge_full_name ?? ''
                        );
                    case 'name_desc':
                        return (b.event_badge_full_name ?? '').localeCompare(
                            a.event_badge_full_name ?? ''
                        );
                    case 'created_asc':
                        return (
                            new Date(a.created_on || 0).getTime() -
                            new Date(b.created_on || 0).getTime()
                        );
                    case 'created_desc':
                        return (
                            new Date(b.created_on || 0).getTime() -
                            new Date(a.created_on || 0).getTime()
                        );
                    default:
                        return (
                            new Date(b.created_on || 0).getTime() -
                            new Date(a.created_on || 0).getTime()
                        );
                }
            });

            const local_ids = local_results
                .map((e) => String(e.id || e.event_exhibit_tracking_id))
                .filter(Boolean);

            if (current_search_id === last_search_id) {
                if (log_lvl)
                    console.log(
                        `✅ [Trace] Lead Search #${current_search_id}: Local path found ${local_ids.length} items.`
                    );
                untrack(() => {
                    tracking_id_li = local_ids;
                });
            }
        } catch (e) {
            console.warn('Exhibit Tracking Local Search failed.', e);
        }
    }

    // 2. REVALIDATE: API Request
    try {
        let order_by_li: any = {};
        switch (params.sort) {
            case 'name_asc':
                order_by_li = { event_badge_full_name: 'ASC' };
                break;
            case 'name_desc':
                order_by_li = { event_badge_full_name: 'DESC' };
                break;
            case 'created_asc':
                order_by_li = { created_on: 'ASC' };
                break;
            case 'created_desc':
                order_by_li = { created_on: 'DESC' };
                break;
            default:
                order_by_li = { created_on: 'DESC' };
        }

        const q_event_id: string = page.params.event_id ?? '';
        const q_exhibit_id: string = exhibit_id ?? '';
        const q_licensee_email: string | null =
            params.licensee_email !== 'all'
                ? (params.licensee_email ?? '')
                : null;

        const results = await events_func.search__exhibit_tracking({
            api_cfg: $ae_api,
            event_id: q_event_id,
            event_exhibit_id: q_exhibit_id,
            fulltext_search_qry_str: qry_str || null,
            qry_external_person_id: q_licensee_email,
            hidden: params.show_hidden ? 'all' : 'not_hidden',
            order_by_li,
            limit: 150
        });

        if (current_search_id === last_search_id) {
            const api_ids = results
                .map((e: any) => String(e.id || e.event_exhibit_tracking_id))
                .filter(Boolean);

            if (log_lvl)
                console.log(
                    `📦 [Trace] Lead Search #${current_search_id}: API revalidation found ${api_ids.length} items.`
                );

            untrack(() => {
                tracking_id_li = api_ids;
                $events_sess.leads.submit_status__search = 'done';
                $events_sess.leads.last_refresh_time = new Date().toISOString();
            });
        }
    } catch (error) {
        if (current_search_id === last_search_id) {
            console.error('Lead revalidation failed:', error);
            untrack(() => {
                $events_sess.leads.submit_status__search = 'error';
            });
        }
    }
}

async function handle_export() {
    const exhibit_id = page.params.exhibit_id;
    if (!exhibit_id) return;

    await events_func.download_export__event_exhibit_tracking({
        api_cfg: $ae_api,
        exhibit_id: exhibit_id,
        log_lvl: 1
    });
}

function toggle_main_tab() {
    if (active_tab === 'add') {
        set_active_tab('list');
        previous_main_tab = 'list';
    } else {
        set_active_tab('add');
        previous_main_tab = 'add';
    }
}

function toggle_manage_tab() {
    if (active_tab === 'manage') {
        set_active_tab(previous_main_tab);
    } else {
        set_active_tab('manage');
    }
}
</script>

<section
    class="ae_events_leads_tracking_new flex h-full w-full flex-col items-center overflow-x-hidden">
    <!-- Header -->
    <header
        class="bg-surface-100-900 border-surface-500/20 sticky top-0 z-10 flex w-full items-center justify-between gap-4 border-b px-4 py-2 shadow-sm">
        <div class="flex min-w-0 flex-col">
            <h1 class="truncate text-base leading-tight font-bold sm:text-lg">
                {$lq__exhibit_obj?.name ?? 'Exhibitor'}
            </h1>
            <p class="text-[10px] opacity-60 sm:text-xs">
                Booth #{$lq__exhibit_obj?.code ?? '...'}
            </p>
        </div>

        <div class="flex items-center gap-1 sm:gap-2">
            {#if is_signed_in}
                <!-- Add Lead / Lead List Toggle -->
                <button
                    type="button"
                    class="btn btn-sm preset-filled-primary px-2 font-bold shadow-sm sm:px-4"
                    onclick={toggle_main_tab}>
                    {#if active_tab === 'add'}
                        <ListIcon size="1.25em" class="sm:mr-2" />
                        <span class="hidden sm:inline">Lead List</span>
                    {:else}
                        <Plus size="1.25em" class="sm:mr-2" />
                        <span class="hidden sm:inline">Add Lead</span>
                    {/if}
                </button>

                <!-- Payment (Conditional) — visible only when event-level leads_require_payment is true -->
                {#if leads_require_payment}
                    <button
                        type="button"
                        class="btn btn-sm px-2 transition-colors sm:px-3"
                        class:preset-filled-success={active_tab === 'payment'}
                        class:preset-outlined-success={active_tab !== 'payment'}
                        onclick={() => set_active_tab('payment')}
                        title="Payment & Upgrades">
                        <CreditCard size="1.25em" />
                    </button>
                {/if}

                <!-- Manage / Config -->
                <button
                    type="button"
                    class="btn btn-sm px-2 transition-colors sm:px-3"
                    class:preset-tonal-surface={active_tab === 'manage'}
                    class:preset-outlined-surface={active_tab !== 'manage'}
                    onclick={toggle_manage_tab}
                    title="Manage Exhibit">
                    <Settings size="1.25em" />
                </button>
            {/if}
        </div>
    </header>

    <!-- Main Content Area - Stable Width -->
    <div class="flex w-full flex-1 flex-col items-center">
        <div class="w-full space-y-6 px-4 py-6 sm:px-6">
            {#if !is_signed_in}
                <div class="mx-auto w-full max-w-4xl">
                    <Tab_start />
                </div>
            {:else if active_tab === 'add'}
                <Tab_add exhibit_id={page.params.exhibit_id ?? ''} />
            {:else if active_tab === 'payment' && leads_require_payment}
                <div class="mx-auto w-full max-w-4xl">
                    <Comp_exhibit_payment exhibit_id={page.params.exhibit_id ?? ''} {...stripe_cfg} leads_require_payment={leads_require_payment} />
                </div>
            {:else if active_tab === 'list'}
                <div class="flex w-full flex-col space-y-6">
                    <div class="flex items-center justify-between px-2">
                        <h2 class="text-xl font-bold sm:text-2xl">Lead List</h2>
                        {#if $lq__exhibit_obj?.leads_api_access === true}
                            <button
                                type="button"
                                class="btn btn-sm preset-outlined-secondary"
                                onclick={handle_export}>
                                <Download size="1.2em" class="mr-2" /> Export
                            </button>
                        {/if}
                    </div>

                    <Comp_exhibit_tracking_search
                        exhibit_id={page.params.exhibit_id ?? ''} />

                    {#if $events_sess.leads.submit_status__search === 'searching' && tracking_id_li.length === 0}
                        <div
                            class="flex w-full flex-col items-center justify-center p-10 text-center opacity-50">
                            <LoaderCircle
                                size="3em"
                                class="mx-auto mb-4 animate-spin" />
                            <p class="text-xl">Searching leads...</p>
                        </div>
                    {:else}
                        <Comp_exhibit_tracking_obj_li
                            lq__event_exhibit_tracking_obj_li={filtered_lead_li} />
                    {/if}
                </div>
            {:else if active_tab === 'manage'}
                <div class="mx-auto w-full max-w-4xl">
                    <Tab_manage {leads_require_payment} {stripe_cfg} />
                </div>
            {/if}
        </div>
    </div>
</section>
