<script lang="ts">
/**
 * src/routes/events/[event_id]/(leads)/leads/exhibit/[exhibit_id]/lead/[exhibit_tracking_id]/ae_comp__lead_detail_form.svelte
 * Lead Detail Form - Dynamic Custom Questions Editor.
 *
 * Question schema (event_exhibit.leads_custom_questions_json):
 *   [{ code, question, type, option_li }]
 *   - code:      machine key — used as the property name in responses_json
 *   - question:  human-readable label shown to the exhibitor during capture/review
 *   - type:      'text' | 'textarea' | 'toggle' | 'option'
 *   - option_li: array of choices; first element is always '' (blank default)
 *
 * Response storage (event_exhibit_tracking.responses_json):
 *   { [code]: { response: <value> } }
 *   e.g. { "giveaway": { "response": "yes" }, "interest_level": { "response": "Hot" } }
 *
 * Backward compat: older questions may use `label` instead of `code`/`question`,
 * and older responses may store scalars directly (not wrapped in {response: ...}).
 * Both are handled transparently.
 */
import { untrack } from 'svelte';
import { goto } from '$app/navigation';
import { ae_api } from '$lib/stores/ae_stores';
import { events_func } from '$lib/ae_events/ae_events_functions';
import { leads_loc } from '$lib/stores/ae_events_stores__leads.svelte';
import { ArrowRight, CircleCheck, LoaderCircle, Save, Settings } from '@lucide/svelte';
interface Props {
    exhibit_tracking_id: string;
    exhibit_id: string;
    event_id: string; // For navigate-to-manage link
    custom_questions_json?: string; // From event_exhibit
    current_responses_json?: string; // From event_exhibit_tracking
    is_dirty?: boolean; // Bindable — parent reads this for unsaved-changes guard
}

let {
    exhibit_tracking_id,
    exhibit_id,
    event_id,
    custom_questions_json = '[]',
    current_responses_json = '{}',
    is_dirty = $bindable(false)
}: Props = $props();

let question_defs: any[] = $state([]);
// flat_responses: keyed by question code, stores scalar values for form binding.
// We unwrap the nested {response: value} format on load and re-wrap on save.
let flat_responses: Record<string, any> = $state({});
let status = $state('idle'); // idle, saving, success

// Snapshot of responses as last saved (or as loaded). Used for dirty detection.
let saved_snapshot = $state('{}');

$effect(() => {
    try {
        const defs =
            typeof custom_questions_json === 'string'
                ? JSON.parse(custom_questions_json || '[]')
                : custom_questions_json || [];
        const raw =
            typeof current_responses_json === 'string'
                ? JSON.parse(current_responses_json || '{}')
                : current_responses_json || {};

        untrack(() => {
            question_defs = defs;
            // Flatten: unwrap {response: value} → scalar for form binding
            const flat: Record<string, any> = {};
            for (const [key, val] of Object.entries(raw)) {
                if (
                    val !== null &&
                    typeof val === 'object' &&
                    'response' in (val as object)
                ) {
                    flat[key] = (val as any).response ?? '';
                } else {
                    flat[key] = val ?? ''; // legacy scalar
                }
            }
            flat_responses = flat;
            saved_snapshot = JSON.stringify(flat);
        });
    } catch (e) {
        console.error('Failed to parse questions/responses', e);
    }
});

// Expose dirty state to parent so the unsaved-changes guard can check it.
$effect(() => {
    is_dirty = JSON.stringify(flat_responses) !== saved_snapshot;
});

// Resolve the key for a question def (new: q.code, legacy: q.label)
function q_key(q: any): string {
    return q.code || q.label || '';
}

async function handle_save() {
    if (!exhibit_tracking_id) return;
    status = 'saving';
    try {
        // Re-wrap scalar values back to {response: value} format before saving
        const nested: Record<string, any> = {};
        for (const [key, val] of Object.entries(flat_responses)) {
            nested[key] = { response: val };
        }
        await events_func.update_ae_obj__exhibit_tracking({
            api_cfg: $ae_api,
            exhibit_id: exhibit_id,
            exhibit_tracking_id: exhibit_tracking_id,
            data: {
                responses_json: JSON.stringify(nested)
            }
        });
        saved_snapshot = JSON.stringify(flat_responses); // mark clean
        status = 'success';
        setTimeout(() => (status = 'idle'), 2000);
    } catch (e) {
        console.error('Failed to update responses', e);
        status = 'idle';
    }
}
</script>

<div class="lead-detail-form space-y-6">
    <div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
        {#each question_defs as q (q_key(q))}
            {@const key = q_key(q)}
            {@const display = q.question || q.label || key}
            <div class="space-y-2">
                <label class="label">
                    <span
                        class="ml-1 text-[10px] font-black tracking-widest uppercase opacity-40"
                        >{display}</span>

                    {#if q.type === 'textarea'}
                        <textarea
                            bind:value={flat_responses[key]}
                            class="textarea rounded-lg p-3 text-sm"
                            rows="3"
                            placeholder="Type response..."></textarea>
                    {:else if q.type === 'toggle'}
                        <div
                            class="preset-tonal-surface flex items-center gap-4 rounded-lg p-3">
                            <input
                                type="checkbox"
                                bind:checked={flat_responses[key]}
                                class="checkbox" />
                            <span class="text-sm font-bold"
                                >{flat_responses[key] ? 'Yes' : 'No'}</span>
                        </div>
                    {:else if q.type === 'option' || q.type === 'select'}
                        <!-- type 'option' is the current schema; 'select' is legacy compat -->
                        <select
                            bind:value={flat_responses[key]}
                            class="select rounded-lg p-3 text-sm">
                            {#if Array.isArray(q.option_li)}
                                {#each q.option_li as opt (opt)}
                                    <option value={opt}
                                        >{opt || '-- Select --'}</option>
                                {/each}
                            {:else}
                                <!-- Legacy: options was a comma-separated string -->
                                <option value="">-- Select Option --</option>
                                {#each (q.options || '')
                                    .split(',')
                                    .map((o: string) => o.trim()) as opt (opt)}
                                    <option value={opt}>{opt}</option>
                                {/each}
                            {/if}
                        </select>
                    {:else}
                        <input
                            type="text"
                            bind:value={flat_responses[key]}
                            class="input rounded-lg p-3 text-sm"
                            placeholder="Type response..." />
                    {/if}
                </label>
            </div>
        {/each}
    </div>

    {#if question_defs.length === 0}
        <!-- No questions set up yet — prompt them to configure rather than leaving a dead form. -->
        <div
            class="preset-tonal-surface border-surface-500/20 flex flex-col items-center gap-3 rounded-xl border p-6 text-center">
            <p class="text-sm font-semibold opacity-60">
                No custom questions configured for this exhibit yet.
            </p>
            <button
                type="button"
                class="btn btn-sm preset-outlined-primary"
                onclick={() => {
                    // Set the tab before navigating so the user lands directly in Manage.
                    leads_loc.current.tab[exhibit_id] = 'manage';
                    goto(`/events/${event_id}/leads/exhibit/${exhibit_id}`);
                }}>
                <Settings size="1.1em" class="mr-1" />
                Configure in Manage Tab
                <ArrowRight size="1.1em" class="ml-1" />
            </button>
        </div>
    {:else}
        <button
            class="btn preset-filled-primary w-full font-bold shadow-lg"
            disabled={status === 'saving'}
            onclick={handle_save}>
            {#if status === 'saving'}
                <LoaderCircle size="1.2em" class="mr-2 animate-spin" /> Saving...
            {:else if status === 'success'}
                <CircleCheck size="1.2em" class="mr-2" /> Saved!
            {:else}
                <Save size="1.2em" class="mr-2" /> Save Responses
            {/if}
        </button>
    {/if}
</div>
