<script lang="ts">
import { Loader2 } from '@lucide/svelte';
import type { key_val } from '$lib/stores/ae_stores';
import { events_func } from '$lib/ae_events/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores';
import { api } from '$lib/ae_api/api';

interface Props {
    event_id: string;
    /** Template list for this event. Drives the template selector and badge_type_code_li. */
    template_li?: Array<{ event_badge_template_id?: string | null; name?: string | null; badge_type_list?: string | null }>;
    onsuccess?: (badge: any) => void;
    oncancel?: () => void;
}

// Fallback badge type list used only when no template is loaded yet or the selected
// template has no badge_type_list defined.
// Keep in sync with the list in ae_comp__badge_search.svelte so the create form
// and the search filter always show the same options.
// TODO: drive both from the event's badge template badge_type_list so this is event-agnostic.
const default_badge_type_code_li = [
    { code: 'attendee', name: 'In-Person Attendee' },
    { code: 'sponsor', name: 'Adapt26 Sponsor' },
    { code: 'staff', name: 'Staff' },
    { code: 'guest', name: 'Guest' },
    { code: 'volunteer', name: 'Volunteer' },
    { code: 'member', name: 'Member' },
    { code: 'nonmember', name: 'Non-Member' },
    { code: 'test', name: 'Test' }
];

let {
    event_id,
    template_li = [],
    onsuccess,
    oncancel
}: Props = $props();

let given_name: string = $state('');
let family_name: string = $state('');
let full_name_override: string = $state('');
let professional_title: string = $state('');
let affiliations: string = $state('');
let location: string = $state('');
let email: string = $state('');
let allow_tracking: boolean = $state(false);
let badge_type_code: string = $state('attendee');

// Always pre-select the first template. Every badged event must have at least one template —
// without one the badge cannot render. If there's only one we auto-select silently; if there
// are multiple the dropdown lets the user switch, but we never start with no selection.
// The !selected_template_id guard prevents a reactive re-fire from overriding a user's pick.
let selected_template_id: string = $state('');
$effect(() => {
    if (template_li.length >= 1 && !selected_template_id) {
        selected_template_id = template_li[0].event_badge_template_id ?? '';
    }
});

// Derive badge type options from the selected template's badge_type_list JSON.
// Fall back to the hardcoded default when no template is selected or its list is empty.
let badge_type_code_li = $derived.by(() => {
    const tmpl = template_li.find((t) => t.event_badge_template_id === selected_template_id);
    if (!tmpl?.badge_type_list) return default_badge_type_code_li;
    try {
        const parsed = JSON.parse(tmpl.badge_type_list);
        return Array.isArray(parsed) && parsed.length > 0 ? parsed : default_badge_type_code_li;
    } catch {
        return default_badge_type_code_li;
    }
});

// When the template list loads (async) the derived badge_type_code_li updates.
// Re-apply the preferred default so the select always starts on a real option.
// Preferred: 'attendee'. Fallback: first item in the list.
// Guard: only reset if the current value isn't already in the new list — preserves
// any explicit selection the user made before the template finished loading.
$effect(() => {
    const li = badge_type_code_li;
    if (!li.length) return;
    if (li.some((item) => item.code === badge_type_code)) return; // current value still valid
    const preferred = li.find((item) => item.code === 'attendee');
    badge_type_code = preferred?.code ?? li[0].code;
});

// Only show the name override field if the user explicitly wants to customize it.
// The preview below the name fields shows what the badge will display — if that looks
// good they don't need to touch this.
let show_name_override: boolean = $state(false);

// Live preview of what will print on the badge if no override is set
let full_name_preview = $derived(
    [given_name.trim(), family_name.trim()].filter(Boolean).join(' ') || '—'
);

// 'idle' | 'creating_person' | 'creating_badge' | 'success' | 'error'
let submit_status: string = $state('idle');
let error_msg: string = $state('');

async function handle_submit(event: Event) {
    event.preventDefault();
    submit_status = 'creating_person';
    error_msg = '';

    // Step 1: Create event_person — the identity record for this attendee.
    // The V3 create endpoint returns { event_person_id }.
    // We pass event_person_id to the badge so the backend resolves the FK.
    let new_person: { event_person_id?: string; obj_id?: string; } | null = null;
    try {
        const person_data: key_val = { given_name, family_name, email };
        new_person = await events_func.create_ae_obj__event_person({
            api_cfg: $ae_api,
            event_id,
            data_kv: person_data
        });
    } catch (err) {
        console.error('Error creating event_person:', err);
        submit_status = 'error';
        error_msg = 'Failed to create attendee record.';
        return;
    }

    const event_person_id = new_person?.event_person_id || new_person?.obj_id;
    if (!event_person_id) {
        submit_status = 'error';
        error_msg = 'Attendee record created but returned no ID.';
        return;
    }

    // Step 2: Create event_badge nested under event.
    // POST /v3/crud/event/{event_id}/event_badge/
    // Passing event_person_id so the backend links the badge to the person.
    // Backend needs to handle event_badge creation without injecting event_id as a column
    // (event_badge gets event_id through event_person in the view, not as a direct FK).
    submit_status = 'creating_badge';
    try {
        const badge_data: key_val = {
            event_person_id,
            event_badge_template_id: selected_template_id || null,
            given_name,
            family_name,
            email: email || null,
            full_name_override: full_name_override || null,
            professional_title: professional_title || null,
            affiliations: affiliations || null,
            location: location || null,
            allow_tracking,
            badge_type_code: badge_type_code || null
        };
        const new_badge = await api.create_nested_obj({
            api_cfg: $ae_api,
            parent_type: 'event_person',
            parent_id: event_person_id,
            child_type: 'event_badge',
            fields: badge_data
        });
        if (new_badge?.event_badge_id) {
            submit_status = 'success';
            if (onsuccess) onsuccess(new_badge);
        } else {
            submit_status = 'error';
            error_msg = 'Badge record not returned from API.';
        }
    } catch (err) {
        console.error('Error creating event_badge:', err);
        submit_status = 'error';
        error_msg = `Attendee record created (ID: ${event_person_id}) but badge creation failed.`;
    }
}

function handle_cancel() {
    if (oncancel) oncancel();
}

let is_submitting = $derived(
    submit_status === 'creating_person' || submit_status === 'creating_badge'
);
let step_label = $derived(
    submit_status === 'creating_person'
        ? 'Creating attendee record…'
        : submit_status === 'creating_badge'
          ? 'Creating badge…'
          : ''
);
</script>

<form onsubmit={handle_submit} class="space-y-4 p-5">
    <div class="grid grid-cols-2 gap-3">
        <label class="label">
            <span class="label-text">First Name</span>
            <input
                type="text"
                bind:value={given_name}
                class="input"
                required
                placeholder="Jane" />
        </label>
        <label class="label">
            <span class="label-text">Last Name</span>
            <input
                type="text"
                bind:value={family_name}
                class="input"
                required
                placeholder="Smith" />
        </label>
    </div>

    <!-- Live badge name preview. If it looks right, no override needed. -->
    <div class="flex items-center justify-between gap-2 text-sm">
        <span class="text-surface-400">Badge will show:
            <span class="text-surface-900-50 font-semibold">{full_name_preview}</span>
        </span>
        <button
            type="button"
            class="text-primary-500 hover:text-primary-400 text-xs underline underline-offset-2"
            onclick={() => { show_name_override = !show_name_override; }}>
            {show_name_override ? 'Hide override' : 'Customize display name'}
        </button>
    </div>

    {#if show_name_override}
        <label class="label">
            <span class="label-text">Display Name Override</span>
            <input
                type="text"
                bind:value={full_name_override}
                class="input"
                placeholder="e.g. Dr. Jane Smith, PhD" />
        </label>
    {/if}

    <label class="label">
        <span class="label-text">Email</span>
        <input type="email" bind:value={email} class="input" placeholder="jane@example.com" />
    </label>
    {#if template_li.length === 0}
        <!-- No templates configured — badge cannot render without one. Block submission. -->
        <p class="text-error-600 dark:text-error-400 text-sm font-medium">
            No badge templates are configured for this event. Set up a template before creating badges.
        </p>
    {:else if template_li.length === 1}
        <!-- Single template — auto-selected. Show it so the user can confirm. -->
        <div class="text-sm">
            <span class="text-surface-500">Badge Template:</span>
            <span class="text-surface-900-50 font-medium">{template_li[0].name}</span>
        </div>
    {:else}
        <!-- Multiple templates — let the user pick; always pre-selected to first. -->
        <label class="label">
            <span class="label-text">Badge Template</span>
            <select bind:value={selected_template_id} class="select">
                {#each template_li as tmpl (tmpl.event_badge_template_id)}
                    <option value={tmpl.event_badge_template_id}>{tmpl.name}</option>
                {/each}
            </select>
        </label>
    {/if}
    <label class="label">
        <span class="label-text">Badge Type</span>
        <select bind:value={badge_type_code} class="select">
            {#each badge_type_code_li as item (item.code)}
                <option value={item.code}>{item.name}</option>
            {/each}
        </select>
    </label>

    <hr class="border-surface-300-600" />

    <label class="label">
        <span class="label-text">Professional Title <span class="text-surface-400 font-normal">(optional)</span></span>
        <input type="text" bind:value={professional_title} class="input" placeholder="e.g. Chief Medical Officer" />
    </label>
    <label class="label">
        <span class="label-text">Organization <span class="text-surface-400 font-normal">(optional)</span></span>
        <input type="text" bind:value={affiliations} class="input" placeholder="e.g. Acme Hospital" />
    </label>
    <label class="label">
        <span class="label-text">Location <span class="text-surface-400 font-normal">(optional)</span></span>
        <input type="text" bind:value={location} class="input" placeholder="City, State" />
    </label>
    <label class="flex items-center gap-2">
        <input type="checkbox" bind:checked={allow_tracking} class="checkbox" />
        <span class="text-sm">Allow lead tracking</span>
    </label>

    {#if submit_status === 'error'}
        <p class="text-error-500 text-sm">{error_msg || 'An error occurred. Please try again.'}</p>
    {/if}

    <div class="flex items-center justify-end gap-2">
        {#if is_submitting}
            <span class="text-surface-400 flex items-center gap-1 text-sm">
                <Loader2 size="1em" class="animate-spin" />
                {step_label}
            </span>
        {/if}
        <button
            type="button"
            class="btn preset-tonal-surface"
            disabled={is_submitting}
            onclick={handle_cancel}>Cancel</button>
        <button
            type="submit"
            class="btn preset-filled-primary"
            disabled={is_submitting || !given_name || !family_name || template_li.length === 0}>
            Create Badge
        </button>
    </div>
</form>

<style>
/* Placeholder text must read as a hint, not as filled content.
   Tailwind v4 sets placeholder color too dark on light backgrounds.
   Same fix as ae_comp__badge_print_controls.svelte. */

/* form textarea::placeholder */
form input::placeholder {
    color: #9ca3af; /* gray-400 */
    opacity: 1;     /* Firefox: override default 0.54 opacity */
}

/* :global(.dark) form textarea::placeholder */
:global(.dark) form input::placeholder {
    color: #6b7280; /* gray-500 in dark mode */
}
</style>
