<script lang="ts">
/**
 * src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/ae_comp__lead_manual_search.svelte
 * Manual Attendee Search for adding leads.
 */
import { page } from '$app/state';
import { liveQuery } from 'dexie';
import { db_events } from '$lib/ae_events/db_events';
import { ae_api, ae_loc } from '$lib/stores/ae_stores';
import { leads_loc } from '$lib/stores/ae_events_stores__leads.svelte';
import { events_func } from '$lib/ae_events/ae_events_functions';
import { Eye, LoaderCircle, Search, ShieldOff, UserPlus } from '@lucide/svelte';
import type { ae_EventBadge } from '$lib/types/ae_types';
import { ae_util } from '$lib/ae_utils/ae_utils';

interface Props {
    exhibit_id: string;
    on_lead_added?: (badge: ae_EventBadge) => void;
}

let { exhibit_id, on_lead_added }: Props = $props();

// Track existing leads to prevent duplicates in UI
let existing_leads_map = $derived(
    liveQuery(async () => {
        const leads = await db_events.exhibit_tracking
            .where('event_exhibit_id')
            .equals(exhibit_id)
            .toArray();

        // Map badge_id -> tracking_id
        const map = new Map();
        leads.forEach((l) => {
            const b_id =
                l.event_badge_id_random || l.event_badge_id?.toString();
            if (b_id)
                map.set(
                    b_id,
                    l.event_exhibit_tracking_id_random ||
                        l.event_exhibit_tracking_id?.toString()
                );
        });
        return map;
    })
);

let search_query = $state('');
let results: ae_EventBadge[] = $state([]);
let searching = $state(false);
let adding_id = $state(''); // badge_id currently being added (shows spinner)
let add_error_id = $state(''); // badge_id that failed to add (shows error)
// Track the most recently added badge_id → tracking_id so we can show a View link
let last_added_badge_id = $state('');
let last_added_tracking_id = $state('');

async function handle_search() {
    if (!search_query.trim()) return;
    searching = true;
    add_error_id = '';
    try {
        const search_results = await events_func.search__event_badge({
            api_cfg: $ae_api,
            event_id: page.params.event_id || '',
            fulltext_search_qry_str: search_query,
            limit: 20
        });
        results = Array.isArray(search_results) ? search_results : [];
    } catch (e) {
        console.error('Badge search failed', e);
    } finally {
        searching = false;
    }
}

async function add_as_lead(badge: ae_EventBadge) {
    // Use id or id_random — whichever is populated from search results
    // NO LONGER USE "_random"
    const badge_id = badge.event_badge_id_random || badge.event_badge_id;
    if (!badge_id) {
        console.warn(
            '[add_as_lead] badge missing event_badge_id_random and event_badge_id',
            badge
        );
        return;
    }

    // Gate: attendee must have opted in to lead tracking (allow_tracking must be explicitly true).
    // Defensive guard — the UI already hides the Add button for blocked badges,
    // but this prevents any direct/programmatic calls from bypassing the check.
    if (badge.allow_tracking !== true) {
        console.warn(
            '[add_as_lead] blocked — allow_tracking is not true for badge',
            badge_id
        );
        return;
    }

    adding_id = badge_id;
    add_error_id = '';

    const kv = leads_loc.current.auth_exhibit_kv?.[exhibit_id];
    const user_email =
        kv?.type === 'licensed' && kv.key
            ? kv.key
            : kv?.type === 'shared'
              ? 'shared_passcode'
              : $ae_loc.access_type || 'anonymous';

    try {
        const result = await events_func.create_ae_obj__exhibit_tracking({
            api_cfg: $ae_api,
            exhibit_id: exhibit_id,
            event_badge_id: badge_id,
            external_person_id: user_email,
            group: user_email
        });

        if (result) {
            // Surface a View Details link next to this result row
            last_added_badge_id = badge_id;
            last_added_tracking_id =
                result.event_exhibit_tracking_id_random ||
                String(result.event_exhibit_tracking_id || '');
            if (on_lead_added) on_lead_added(badge);
        } else {
            // API returned null/false — surface a visible error on this row
            add_error_id = badge_id;
            console.warn(
                '[add_as_lead] API returned null for badge_id',
                badge_id
            );
        }
    } catch (e) {
        add_error_id = badge_id;
        console.error('[add_as_lead] Failed to add lead', e);
    } finally {
        adding_id = '';
    }
}
</script>

<div class="lead-manual-search w-full space-y-4">
    <form
        class="search_form preset-tonal-primary flex w-full flex-row flex-wrap items-center justify-center gap-1 rounded-lg px-2 py-2 shadow-sm"
        onsubmit={(e) => {
            e.preventDefault();
            handle_search();
        }}>
        <div
            class="flex grow flex-col items-center justify-center gap-1 md:flex-row">
            <input
                type="search"
                bind:value={search_query}
                placeholder="Attendee name, email, or badge ID..."
                class="input w-full grow font-mono text-lg transition-all" />
        </div>

        <div class="flex flex-row items-center justify-center gap-1">
            <button
                type="submit"
                class="btn btn-lg preset-tonal-primary border-primary-500 hover:preset-tonal-primary w-48 border text-2xl font-bold transition-all"
                disabled={searching}>
                {#if searching}
                    <LoaderCircle class="mx-1 animate-spin" size="1.2em" />
                {:else}
                    <Search class="mx-1" size="1.2em" />
                {/if}
                Search
            </button>
        </div>
    </form>

    {#if results.length > 0}
        <div class="results-list max-h-[50vh] space-y-2 overflow-y-auto pr-2">
            {#each results as badge (badge.event_badge_id_random ?? badge.event_badge_id)}
                {@const badge_id =
                    badge.event_badge_id_random || badge.event_badge_id}
                {@const existing_id =
                    $existing_leads_map?.get(badge_id) ??
                    (last_added_badge_id === badge_id
                        ? last_added_tracking_id
                        : '')}
                <div
                    class="card preset-tonal-surface flex items-center justify-between p-3 shadow-sm">
                    <div>
                        <div class="font-bold">{badge.full_name}</div>
                        <div class="text-xs opacity-70">
                            {badge.affiliations || badge.email || ''}
                        </div>
                    </div>

                    {#if existing_id}
                        <a
                            href={`/events/${page.params.event_id}/leads/exhibit/${exhibit_id}/lead/${existing_id}`}
                            class="btn btn-sm preset-filled-secondary">
                            <Eye size="1em" class="mr-1" />
                            View
                        </a>
                    {:else if badge.allow_tracking !== true}
                        <!-- Attendee has not opted in to tracking — cannot add as lead -->
                        <span
                            class="text-warning-500 flex items-center gap-1 text-xs font-bold opacity-70"
                            title="This attendee has not opted in to exhibitor lead tracking.">
                            <ShieldOff size="1em" />
                            Opt-Out
                        </span>
                    {:else if add_error_id === badge_id}
                        <span class="text-error-500 text-xs font-bold"
                            >Add failed — retry?
                            <button
                                type="button"
                                class="btn btn-sm preset-outlined-error ml-1"
                                onclick={() => add_as_lead(badge)}>
                                Retry
                            </button>
                        </span>
                    {:else}
                        <button
                            type="button"
                            class="btn btn-sm preset-filled-success"
                            disabled={!!adding_id && adding_id === badge_id}
                            onclick={() => add_as_lead(badge)}>
                            {#if adding_id === badge_id}
                                <LoaderCircle class="animate-spin" size="1em" />
                            {:else}
                                <UserPlus size="1em" class="mr-1" />
                            {/if}
                            Add
                        </button>
                    {/if}
                </div>
            {/each}
        </div>
    {:else if !searching && search_query}
        <p class="py-4 text-center italic opacity-50">
            No attendees found matching "{search_query}"
        </p>
    {/if}
</div>
