//! Scene list popup component for teleport command.
//!
//! Shows available scenes in a realm for teleportation.

use leptos::prelude::*;

use chattyness_db::models::SceneSummary;

/// Scene list popup component.
///
/// Shows scenes in a list with keyboard navigation for teleport selection.
///
/// Props:
/// - `scenes`: List of available scenes
/// - `on_select`: Callback when a scene is selected (receives SceneSummary)
/// - `on_close`: Callback when popup should close
/// - `scene_filter`: Signal containing the current filter text
/// - `selected_idx`: Signal containing the currently selected index
#[component]
pub fn SceneListPopup(
    scenes: Signal<Vec<SceneSummary>>,
    on_select: Callback<SceneSummary>,
    #[prop(into)] on_close: Callback<()>,
    #[prop(into)] scene_filter: Signal<String>,
    #[prop(into)] selected_idx: Signal<usize>,
) -> impl IntoView {
    let _ = on_close; // Suppress unused warning

    // Get list of scenes, filtered by search text
    let filtered_scenes = move || {
        let filter_text = scene_filter.get().to_lowercase();
        scenes
            .get()
            .into_iter()
            .filter(|s| {
                filter_text.is_empty()
                    || s.name.to_lowercase().contains(&filter_text)
                    || s.slug.to_lowercase().contains(&filter_text)
            })
            .collect::<Vec<_>>()
    };

    let filter_display = move || {
        let f = scene_filter.get();
        if f.is_empty() {
            "Type to filter...".to_string()
        } else {
            format!("Filter: {}", f)
        }
    };

    // Indexed scenes for selection tracking
    let indexed_scenes = move || {
        filtered_scenes()
            .into_iter()
            .enumerate()
            .collect::<Vec<_>>()
    };

    view! {
        <div
            class="absolute bottom-full left-0 mb-2 w-full max-w-lg bg-gray-800/95 backdrop-blur-sm rounded-lg shadow-2xl border border-gray-700 p-3 z-50"
            role="listbox"
            aria-label="Available scenes"
        >
            <div class="flex justify-between items-center text-xs mb-2 px-1">
                <span class="text-gray-400">"Select a scene to teleport to:"</span>
                <span class="text-blue-400 italic">{filter_display}</span>
            </div>
            <div class="flex flex-col gap-1 max-h-64 overflow-y-auto">
                {move || {
                    indexed_scenes()
                        .into_iter()
                        .map(|(idx, scene)| {
                            let on_select = on_select.clone();
                            let scene_for_click = scene.clone();
                            let scene_name = scene.name.clone();
                            let scene_slug = scene.slug.clone();
                            let is_selected = move || selected_idx.get() == idx;
                            view! {
                                <button
                                    type="button"
                                    class=move || {
                                        if is_selected() {
                                            "flex flex-col gap-0.5 p-2 rounded bg-blue-600 text-left w-full"
                                        } else {
                                            "flex flex-col gap-0.5 p-2 rounded hover:bg-gray-700 transition-colors text-left w-full"
                                        }
                                    }
                                    on:click=move |_| on_select.run(scene_for_click.clone())
                                    role="option"
                                    aria-selected=is_selected
                                >
                                    <span class="text-white text-sm font-medium">
                                        {scene_name}
                                    </span>
                                    <span class="text-gray-400 text-xs">
                                        "/teleport "{scene_slug}
                                    </span>
                                </button>
                            }
                        })
                        .collect_view()
                }}
            </div>
            <Show when=move || filtered_scenes().is_empty()>
                <div class="text-gray-500 text-sm text-center py-4">
                    {move || {
                        if scene_filter.get().is_empty() {
                            "No scenes available"
                        } else {
                            "No matching scenes"
                        }
                    }}
                </div>
            </Show>
            <div class="mt-2 pt-2 border-t border-gray-700 text-xs text-gray-500">
                <kbd class="px-1 py-0.5 bg-gray-700 rounded font-mono">"^_"</kbd>
                " navigate  "
                <kbd class="px-1 py-0.5 bg-gray-700 rounded font-mono">"Enter"</kbd>
                " select  "
                <kbd class="px-1 py-0.5 bg-gray-700 rounded font-mono">"Esc"</kbd>
                " cancel"
            </div>
        </div>
    }
}
