//! Client-side navigation menu wrapper
//!
//! Loads menu items via `load_reactive_menu_for_language`, which reads from
//! `MENU_REGISTRY` (populated at WASM init from compile-time embedded TOML).
//! This mirrors exactly what `NavMenuSSR` does on the server, preventing
//! hydration cursor desynchronization caused by item count differences.

use ::rustelo_core_lib::state::use_language;
use leptos::prelude::*;

/// Client-side reactive navigation menu wrapper (without navigation signals)
#[component]
pub fn NavMenu() -> impl IntoView {
    let language_context = use_language();

    // Pure CSR — no SSR/hydration concerns, so subscribe reactively to language
    // changes. This ensures the menu updates immediately when the user switches
    // language via the selector.
    view! {
        {move || {
            let current_lang = language_context.current.get();
            let menu_items =
                rustelo_core_lib::load_reactive_menu_for_language(&current_lang).unwrap_or_default();

            #[cfg(target_arch = "wasm32")]
            web_sys::console::log_1(
                &format!(
                    "📋 NavMenu: Rendering menu for language '{}' ({} items)",
                    current_lang,
                    menu_items.len()
                )
                .into(),
            );

            view! {
                <crate::navigation::navmenu::unified::UnifiedNavMenu
                    language=current_lang.clone()
                    menu_items=menu_items
                />
            }
        }}
    }
}

// Backward compatibility: NavMenuClient with signals support
#[component]
pub fn NavMenuClient(
    #[prop(optional)] set_path: Option<WriteSignal<String>>,
    #[prop(optional)] path: Option<ReadSignal<String>>,
) -> impl IntoView {
    // If signals provided, use them; otherwise just render reactive menu
    if let (Some(set_path), Some(path)) = (set_path, path) {
        let language_context = use_language();
        view! {
            {move || {
                let current_lang = language_context.current.get();
                let menu_items =
                    rustelo_core_lib::load_reactive_menu_for_language(&current_lang)
                        .unwrap_or_default();

                view! {
                    <crate::navigation::navmenu::unified::UnifiedNavMenu
                        navigation_signals=(path, set_path)
                        language=current_lang
                        menu_items=menu_items
                    />
                }
            }}
        }
        .into_any()
    } else {
        view! { <NavMenu /> }.into_any()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_menu_registry_empty() {
        let registry = MenuRegistry::new();
        assert_eq!(registry.language_count(), 0);
        assert!(registry.available_languages().is_empty());
    }

    #[test]
    fn test_menu_registry_insert_and_get() {
        let mut registry = MenuRegistry::new();
        let menu_items = vec![];

        registry.insert("en", menu_items.clone());

        assert_eq!(registry.language_count(), 1);
        assert!(registry.contains_language("en"));
        assert_eq!(registry.get("en"), Some(&menu_items));
    }

    #[test]
    fn test_menu_registry_multiple_languages() {
        let mut registry = MenuRegistry::new();
        registry.insert("en", vec![]);
        registry.insert("es", vec![]);
        registry.insert("fr", vec![]);

        assert_eq!(registry.language_count(), 3);

        let languages = registry.available_languages();
        assert!(languages.contains(&"en".to_string()));
        assert!(languages.contains(&"es".to_string()));
        assert!(languages.contains(&"fr".to_string()));
    }

    #[test]
    fn test_menu_registry_get_cloned() {
        let mut registry = MenuRegistry::new();
        registry.insert("en", vec![]);

        let cloned = registry.get_cloned("en");
        assert!(cloned.is_some());
        assert_eq!(cloned.unwrap(), vec![]);
    }

    #[test]
    fn test_menu_registry_get_missing_language() {
        let registry = MenuRegistry::new();
        assert!(registry.get("en").is_none());
        assert!(registry.get_cloned("en").is_none());
        assert!(!registry.contains_language("en"));
    }
}
