//! Language-agnostic routing utilities
//!
//! This module re-exports all routing utilities from the split modules.
//! The original large utils.rs file has been split into smaller, focused modules.

// Re-export from split modules
pub use super::config::*;
pub use super::language::*;
pub use super::url_generation::*;
pub use super::mapping::*;
pub use super::seo::*;

// Cache for route mappings to avoid rebuilding on every navigation
static ROUTE_MAPPINGS_CACHE: OnceLock<(HashMap<String, String>, HashMap<String, String>)> =
    OnceLock::new();

// Force cache invalidation after priority logic change
#[allow(dead_code)]
fn invalidate_route_cache() {
    // This would require unsafe code to reset, so we'll rely on recompilation
}

/// Cached routes loaded from TOML configuration
static ROUTES_CACHE: OnceLock<RoutesConfig> = OnceLock::new();

/// Load routes from the routes/ directory using SITE_CONFIG_PATH environment variable
#[cfg(all(not(target_arch = "wasm32"), not(has_generated_resources)))]
fn load_routes_from_directory() -> Option<RoutesConfig> {
    use std::fs;
    use std::path::PathBuf;

    // Get the config path from environment variable
    let config_path = match std::env::var("SITE_CONFIG_PATH") {
        Ok(path) => path,
        Err(_) => {
            // Fallback to common paths
            let fallback_paths = [
                "site/config",
                "content/config",
                "config",
                "../../site/config",
                "../../content/config",
                "../../../site/config",
                "../../../content/config",
            ];

            // Find first existing config directory
            let mut found_path = None;
            for path in &fallback_paths {
                if PathBuf::from(path).exists() {
                    found_path = Some(path.to_string());
                    break;
                }
            }

            match found_path {
                Some(path) => {
                    tracing::info!("Using fallback config path: {}", path);
                    path
                }
                None => {
                    tracing::warn!("No SITE_CONFIG_PATH set and no fallback config directories found");
                    return None;
                }
            }
        }
    };

    let routes_dir = PathBuf::from(&config_path).join("routes");

    if !routes_dir.exists() || !routes_dir.is_dir() {
        tracing::warn!("Routes directory not found at: {}", routes_dir.display());
        return None;
    }

    let mut all_routes = Vec::new();

    // Read all .toml files in the routes directory
    match fs::read_dir(&routes_dir) {
        Ok(entries) => {
            for entry in entries {
                if let Ok(entry) = entry {
                    let path = entry.path();

                    // Only process .toml files
                    if path.extension().and_then(|s| s.to_str()) == Some("toml") {
                        match fs::read_to_string(&path) {
                            Ok(content) => {
                                match toml::from_str::<RoutesConfig>(&content) {
                                    Ok(config) => {
                                        tracing::info!("Loaded routes from: {}", path.display());
                                        all_routes.extend(config.routes);
                                    }
                                    Err(e) => {
                                        tracing::error!("Failed to parse routes from {}: {}", path.display(), e);
                                    }
                                }
                            }
                            Err(e) => {
                                tracing::error!("Failed to read routes file {}: {}", path.display(), e);
                            }
                        }
                    }
                }
            }
        }
        Err(e) => {
            tracing::error!("Failed to read routes directory {}: {}", routes_dir.display(), e);
            return None;
        }
    }

    if all_routes.is_empty() {
        tracing::warn!("No route files found in {}", routes_dir.display());
        return None;
    }

    tracing::info!("Successfully loaded {} routes from {} .toml files", all_routes.len(), routes_dir.display());
    Some(RoutesConfig { routes: all_routes })
}

/// Load routes from TOML configuration
pub fn load_routes_config() -> &'static RoutesConfig {
    ROUTES_CACHE.get_or_init(|| {
        // Check if we have generated resources available
        #[cfg(has_generated_resources)]
        {
            // Try to load from embedded content (for both WASM and server builds)
            let toml_content = include_str!(concat!(env!("OUT_DIR"), "/embedded_routes.toml"));
            match toml::from_str(toml_content) {
                Ok(config) => return config,
                Err(e) => {
                    tracing::warn!("Failed to parse embedded routes.toml: {}", e);
                }
            }
        }

        // For server builds without embedded resources, try file system
        #[cfg(all(not(target_arch = "wasm32"), not(has_generated_resources)))]
        {
            use std::fs;

            // Try to load from routes/ directory using SITE_CONFIG_PATH
            if let Some(config) = load_routes_from_directory() {
                return config;
            }

            // Fallback to legacy single routes.toml files
            let possible_paths = [
                "site/config/routes.toml",
                "content/routes.toml",
                "../../site/config/routes.toml",
                "../../content/routes.toml",
                "../../../site/config/routes.toml",
                "../../../content/routes.toml",
            ];

            for path in &possible_paths {
                if let Ok(content) = fs::read_to_string(path) {
                    match toml::from_str(&content) {
                        Ok(config) => return config,
                        Err(e) => {
                            tracing::warn!("Failed to parse routes.toml from {}: {}", path, e);
                            continue;
                        }
                    }
                }
            }

            tracing::warn!("Could not load routes from file system, using default configuration");
        }

        // Fallback to default configuration
        tracing::warn!(
            "Using default routes configuration - no embedded or file system routes found"
        );
        default_routes_config()
    })
}

/// Default routes configuration (dynamically generated for all available languages)
/// This is only used as a final fallback when embedded routes fail to load
fn default_routes_config() -> RoutesConfig {
    let language_registry = get_language_registry();
    let available_languages = language_registry.get_available_languages();
    let default_language = language_registry.get_default_language();

    let mut routes = Vec::new();

    // Minimal core routes that should exist for basic functionality
    // Only essential routes are included in the fallback
    for language in &available_languages {
        // Home route - always needs to exist
        let home_path = if language == default_language {
            "/"
        } else {
            // For non-default languages, use language prefix format
            &format!("/{}", language)
        };

        routes.push(RouteConfigToml {
            path: home_path.to_string(),
            component: "Home".to_string(),
            title_key: "home-page-title".to_string(),
            language: language.clone(),
            enabled: true,
            description_key: Some("home-page-description".to_string()),
            keywords: Some(vec![
                "home".to_string(),
                "rust".to_string(),
                "developer".to_string(),
            ]),
            priority: Some(1.0),
            menu_group: Some("main".to_string()),
            menu_order: Some(1),
            menu_icon: Some("home".to_string()),
            is_external: None,
            requires_auth: None,
            show_in_sitemap: Some(true),
            alternate_paths: None,
            canonical_path: Some(home_path.to_string()),
            content_type: None,
            props: None,
            unified_component: Some("UnifiedHomePage".to_string()),
            lang_prefixes: Some(vec!["home-".to_string(), "welcome-".to_string()]),
            params_component: Some(std::collections::HashMap::new()),
        });

        // 404 Not Found route - essential for error handling
        let not_found_path = if language == default_language {
            "/404"
        } else {
            &format!("/{}/404", language)
        };

        routes.push(RouteConfigToml {
            path: not_found_path.to_string(),
            component: "UnifiedNotFoundPage".to_string(),
            title_key: "not-found-page-title".to_string(),
            language: language.clone(),
            enabled: true,
            description_key: Some("not-found-page-description".to_string()),
            keywords: Some(vec![
                "404".to_string(),
                "not-found".to_string(),
                "error".to_string(),
            ]),
            priority: Some(0.0),
            menu_group: None,
            menu_order: None,
            menu_icon: None,
            is_external: None,
            requires_auth: None,
            show_in_sitemap: Some(false),
            alternate_paths: None,
            canonical_path: None,
            content_type: None,
            props: None,
            unified_component: Some("UnifiedNotFoundPage".to_string()),
            lang_prefixes: Some(vec!["error-".to_string(), "404-".to_string()]),
            params_component: Some(std::collections::HashMap::new()),
        });
    }

    tracing::warn!(
        "Using fallback default routes configuration with {} minimal routes for {} languages. Consider adding proper route files in content/routes/",
        routes.len(),
        available_languages.len()
    );

    RoutesConfig { routes }
}

/// Build route mappings from loaded configuration (dynamic for all languages)
pub fn build_route_mappings() -> (HashMap<String, String>, HashMap<String, String>) {
    // Use cached mappings if available
    if let Some(cached) = ROUTE_MAPPINGS_CACHE.get() {
        return cached.clone();
    }

    // Build mappings and cache them
    let mappings = build_route_mappings_uncached();
    let _ = ROUTE_MAPPINGS_CACHE.set(mappings.clone());
    mappings
}

fn build_route_mappings_uncached() -> (HashMap<String, String>, HashMap<String, String>) {
    let config = load_routes_config();
    let language_registry = get_language_registry();
    let available_languages = language_registry.get_available_languages();
    let default_language = language_registry.get_default_language();

    let mut mappings = HashMap::new();
    let mut reverse_mappings = HashMap::new();

    // Group routes by component (path, priority)
    let mut routes_by_component: HashMap<String, HashMap<String, (String, f32)>> = HashMap::new();

    // Building route mappings from configuration

    for route in &config.routes {
        if !route.enabled {
            continue;
        }

        // Processing route: component grouping

        let component_map = routes_by_component
            .entry(route.component.clone())
            .or_default();

        // Prioritize localized routes over /lang/ prefix routes and use priority values
        if let Some((existing_path, existing_priority)) = component_map.get(&route.language) {
            let existing_is_prefix = existing_path.starts_with(&format!("/{}/", route.language));
            let new_is_prefix = route.path.starts_with(&format!("/{}/", route.language));
            let new_priority = route.get_priority();

            // Prioritization logic:
            // 1. Prefer localized routes (non-prefix) over /lang/ prefix routes
            // 2. If both are same type (prefix/non-prefix), prefer higher priority
            let should_replace = if existing_is_prefix && !new_is_prefix {
                true // Always prefer localized over prefix
            } else if !existing_is_prefix && new_is_prefix {
                false // Always keep localized over prefix
            } else {
                // Both are same type, use priority
                new_priority > *existing_priority
            };

            if should_replace {
                component_map.insert(route.language.clone(), (route.path.clone(), new_priority));
            }
        } else {
            component_map.insert(
                route.language.clone(),
                (route.path.clone(), route.get_priority()),
            );
        }
    }

    // Build mappings between languages (for the most common two-language scenario)
    for component_routes in routes_by_component.values() {
        let default_route = component_routes.get(default_language);

        for language in &available_languages {
            if language == default_language {
                continue;
            }

            if let (Some((default_path, _)), Some((lang_path, _))) =
                (default_route, component_routes.get(language))
            {
                // Create bidirectional mapping

                mappings.insert(default_path.clone(), lang_path.clone());
                reverse_mappings.insert(lang_path.clone(), default_path.clone());
            }
        }
    }

    // Route mappings built successfully

    (mappings, reverse_mappings)
}

/// Extract language and clean path from a URL path (dynamic language detection)
pub fn extract_lang_and_path(path: &str) -> (String, String) {
    let language_registry = get_language_registry();
    let available_languages = language_registry.get_available_languages();
    let default_language = language_registry.get_default_language();

    // Handle empty or root path
    if path.is_empty() || path == "/" {
        return (default_language.to_string(), "/".to_string());
    }

    // Check if path starts with any language prefix
    for lang in &available_languages {
        if lang == default_language {
            continue; // Skip default language prefix check
        }

        let prefix = format!("/{lang}");
        if let Some(rest) = path.strip_prefix(&prefix) {
            if rest.is_empty() || rest == "/" {
                return (lang.clone(), "/".to_string());
            } else if rest.starts_with('/') {
                // Check for double-prefix scenarios and normalize them
                // e.g., "/es/blog-es/..." should be "/blog-es/..."
                // Use configuration to detect language-specific paths
                let config = load_routes_config();
                for route in &config.routes {
                    if route.enabled
                        && route.language == *lang
                        && rest.starts_with(&route.path.split('{').next().unwrap_or(""))
                    {
                        // Found a localized route that shouldn't have the /lang/ prefix
                        return (lang.clone(), rest.to_string());
                    }
                }
                return (lang.clone(), rest.to_string());
            }
        }
    }

    // Check route configuration for both exact matches and language-specific patterns
    let config = load_routes_config();

    // First check for language-specific content paths (before exact route matches)
    for route in &config.routes {
        if !route.enabled {
            continue;
        }

        // Check if the path starts with a language-specific route pattern
        let route_prefix = route.path.split('{').next().unwrap_or(&route.path);
        if path.starts_with(route_prefix) && route.language != default_language {
            return (route.language.clone(), path.to_string());
        }
    }

    // Check if this exact path exists in route configuration (language-agnostic)
    for route in &config.routes {
        if route.enabled && route.path == path {
            // For default language routes, return clean path; for others, use reverse mapping
            if route.language == default_language {
                return (route.language.clone(), path.to_string());
            } else {
                // Use reverse mapping to get the canonical/clean path
                let (_, reverse_mappings) = build_route_mappings();
                let clean_path = reverse_mappings
                    .get(path)
                    .cloned()
                    .unwrap_or_else(|| path.to_string());
                return (route.language.clone(), clean_path);
            }
        }
    }

    // For certain URL patterns that should always default to the default language,
    // ignore localStorage preferences to avoid confusion
    #[cfg_attr(not(target_arch = "wasm32"), allow(unused_variables))]
    let should_default_to_base_lang = {
        // Check if this path belongs to default language routes
        let config = load_routes_config();
        let default_language = get_language_registry().get_default_language();
        config.routes.iter().any(|route| {
            route.enabled
                && route.language == default_language
                && (route.path == path
                    || path.starts_with(&route.path.replace("{", "").replace("}", "")))
        })
    };

    // For unknown routes, check for stored language preference in cookies to maintain context (language-agnostic)
    // but only if the path doesn't explicitly indicate it should use default language
    #[cfg(target_arch = "wasm32")]
    {
        if !should_default_to_base_lang {
            // Check cookie for language preference (matching i18n.rs implementation)
            match js_sys::eval("document.cookie") {
                Ok(cookie_value) => {
                    if let Some(cookie_string) = cookie_value.as_string() {
                        for cookie in cookie_string.split(';') {
                            let cookie = cookie.trim();
                            if let Some(value) = cookie.strip_prefix("preferred_language=") {
                                let available_languages =
                                    language_registry.get_available_languages();
                                if available_languages.contains(&value.to_string())
                                    && value != default_language
                                {
                                    return (value.to_string(), path.to_string());
                                }
                            }
                        }
                    }
                }
                Err(_) => {}
            }
        }
    }

    // Default to default language
    (default_language.to_string(), path.to_string())
}

/// Detect language from URL path
pub fn detect_language_from_path(path: &str) -> String {
    extract_lang_and_path(path).0
}

/// Check if a route is for a specific language
pub fn is_lang_route(path: &str, target_lang: &str) -> bool {
    let (detected_lang, _) = extract_lang_and_path(path);
    detected_lang == target_lang
}

/// Generate language-aware category URL using route configuration
/// Returns the correct localized path based on language and category parameter
pub fn get_category_url(base_path: &str, category: &str, language: &str) -> String {
    let config = load_routes_config();
    let category_normalized = category.replace(" ", "-").to_lowercase();

    // Find parametric route with {category} placeholder for this language
    let parametric_route = config.routes.iter().find(|route| {
        route.enabled
            && route.language == language
            && route.path.contains("{category}")
            && route.path.starts_with(base_path)
    });

    if let Some(route) = parametric_route {
        // Replace the {category} parameter with the actual category
        let result = route.path.replace("{category}", &category_normalized);
        tracing::debug!(
            "Found parametric route for {}/{}: {} -> {}",
            base_path,
            language,
            route.path,
            result
        );
        result
    } else {
        // Fallback: find base route that matches the base_path and append category
        let base_route = config
            .routes
            .iter()
            .find(|route| route.enabled && route.language == language && route.path == base_path);

        if let Some(base) = base_route {
            // Use the base route path and append category
            let result = format!("{}/{}", base.path, category_normalized);
            tracing::debug!(
                "Using base route fallback for {}/{}: {} -> {}",
                base_path,
                language,
                base.path,
                result
            );
            result
        } else {
            // Final fallback: construct URL using the provided base_path
            let result = format!("{}/{}", base_path, category_normalized);
            tracing::warn!(
                "No route configuration found for {} in language {}, using generic path: {}",
                base_path,
                language,
                result
            );
            result
        }
    }
}

/// Generate language-aware tag URL
/// Alias for get_category_url since tags and categories use the same URL structure
pub fn get_tag_url(base_path: &str, tag: &str, language: &str) -> String {
    get_category_url(base_path, tag, language)
}

/// Get the base path for a component in a specific language from route configuration
pub fn get_component_base_path(component: &str, language: &str) -> Option<String> {
    let config = load_routes_config();

    #[cfg(not(target_arch = "wasm32"))]
    tracing::debug!(
        "🔍 get_component_base_path: Looking for component='{}', language='{}'",
        component,
        language
    );

    let result = config
        .routes
        .iter()
        .find(|route| {
            let matches = route.enabled
                && route.language == language
                && route.component == component
                && !route.path.contains("{"); // Find non-parametric routes

            #[cfg(not(target_arch = "wasm32"))]
            if matches {
                tracing::debug!("✅ get_component_base_path: Found route: path='{}', component='{}', language='{}'", route.path, route.component, route.language);
            }
            matches
        })
        .map(|route| route.path.clone());

    #[cfg(not(target_arch = "wasm32"))]
    if let Some(ref path) = result {
        tracing::debug!(
            "✅ get_component_base_path: Returning path='{}' for component='{}', language='{}'",
            path,
            component,
            language
        );
    } else {
        tracing::warn!(
            "❌ get_component_base_path: No route found for component='{}', language='{}'",
            component,
            language
        );
    }

    result
}

/// Get canonical URL for a given path and language using route configuration
pub fn get_canonical_url(path: &str, language: &str, base_url: &str) -> String {
    let config = load_routes_config();
    let (_, clean_path) = extract_lang_and_path(path);

    // Find the route in route configuration for this language
    if let Some(route) = config.routes.iter().find(|r| {
        r.enabled
            && r.language == language
            && (r.path == path
                || r.canonical_path
                    .as_ref()
                    .map_or(false, |cp| cp == &clean_path))
    }) {
        if route.path == "/" {
            base_url.to_string()
        } else {
            format!("{base_url}{}", route.path)
        }
    } else {
        // Fallback: use the path as-is
        if path == "/" {
            base_url.to_string()
        } else {
            format!("{base_url}{path}")
        }
    }
}

/// Get localized route for a given path using configuration-based routing
/// Get the base path for a content type in a specific language
/// This directly looks up the route definition for a content type in the target language
pub fn get_content_type_base_path(content_type: &str, target_language: &str) -> Option<String> {
    let config = load_routes_config();

    #[cfg(target_arch = "wasm32")]
    web_sys::console::log_1(
        &format!(
            "🔍 get_content_type_base_path: Looking for content_type='{}' in language='{}'",
            content_type, target_language
        ).into(),
    );

    // Find the route for the target language and content type
    let result = config.routes.iter()
        .find(|r| {
            r.enabled
            && r.language == target_language
            && r.get_content_type().as_deref() == Some(content_type)
        })
        .map(|route| {
            #[cfg(target_arch = "wasm32")]
            web_sys::console::log_1(
                &format!(
                    "✅ get_content_type_base_path: Found route path='{}' for content_type='{}' in language='{}'",
                    route.path, content_type, target_language
                ).into(),
            );
            route.path.clone()
        });

    if result.is_none() {
        #[cfg(target_arch = "wasm32")]
        web_sys::console::log_1(
            &format!(
                "⚠️ get_content_type_base_path: No route found for content_type='{}' in language='{}'",
                content_type, target_language
            ).into(),
        );
    }

    result
}

/// Fast version of get_localized_route without console logging for performance
/// Convert content post URLs between languages (handles dynamic slugs)
/// Generic function that works with any content type component (BlogPost, RecipePost, etc.)
pub fn convert_content_post_url(
    path: &str,
    current_lang: &str,
    target_language: &str,
) -> Option<String> {
    #[cfg(target_arch = "wasm32")]
    web_sys::console::log_1(
        &format!(
            "🔄 WASM convert_content_post_url: '{}' from '{}' to '{}'",
            path, current_lang, target_language
        ).into(),
    );

    #[cfg(not(target_arch = "wasm32"))]
    tracing::warn!(
        "🔄 convert_content_post_url: '{}' from '{}' to '{}'",
        path, current_lang, target_language
    );

    let config = load_routes_config();

    // Check if this is a content post URL pattern by looking for matching routes
    // Sort routes by specificity (more parameters = more specific) and then by priority
    let mut sorted_routes = config.routes.clone();
    sorted_routes.sort_by(|a, b| {
        // First compare by parameter count (more specific patterns first)
        let a_param_count = a.path.matches('{').count();
        let b_param_count = b.path.matches('{').count();

        match b_param_count.cmp(&a_param_count) { // Higher param count first
            std::cmp::Ordering::Equal => {
                // If same parameter count, compare by priority (higher priority first)
                b.priority.partial_cmp(&a.priority).unwrap_or(std::cmp::Ordering::Equal)
            }
            other => other,
        }
    });

    #[cfg(target_arch = "wasm32")]
    web_sys::console::log_1(
        &format!("🔍 ROUTE MATCHING: Checking {} routes for path '{}'", sorted_routes.len(), path).into(),
    );

    for current_route in &sorted_routes {
        if !current_route.enabled || current_route.language != current_lang {
            continue;
        }

        // Check if this route matches a content pattern with category and/or slug
        // Works with BlogPost, RecipePost, or any other content type with parametric routes
        // Handles both post URLs ({category}/{slug}) and category URLs ({category} only)
        if current_route.path.contains("{category}") || current_route.path.contains("{slug}") {
            #[cfg(target_arch = "wasm32")]
            web_sys::console::log_1(
                &format!("🔍 TRYING PATTERN: '{}' with {} parameters", current_route.path, current_route.path.matches('{').count()).into(),
            );

            // Try to match the path against this route pattern
            if let Some((category, current_slug)) =
                extract_content_params(&current_route.path, path)
            {
                #[cfg(target_arch = "wasm32")]
                web_sys::console::log_1(
                    &format!(
                        "🔍 EXTRACT PARAMS: pattern='{}', url='{}' => category='{}', slug='{}'",
                        current_route.path, path, category, current_slug
                    ).into(),
                );
                // Find corresponding route in target language with the same component AND content_type
                // First, get the current route's content_type
                let current_content_type = current_route.get_content_type();

                if let Some(target_route) = config.routes.iter().find(|r| {
                    r.enabled
                        && r.language == target_language
                        && r.component == current_route.component // Same component type
                        // Match route pattern: both routes must have the same parameter structure
                        && ((current_route.path.contains("{category}") && r.path.contains("{category}")) ||
                            (current_route.path.contains("{slug}") && r.path.contains("{slug}")))
                        // CRITICAL: Prioritize content_type matching when available
                        && (current_content_type.is_none() ||
                            r.get_content_type() == current_content_type)
                }) {
                    // Get content type from route configuration or derive from component
                    let content_type = current_route
                        .get_content_type()
                        .or_else(|| {
                            crate::get_content_type_from_component(&current_route.component)
                        })
                        .unwrap_or_else(|| {
                            {
                                // Fallback: extract from route path or use component name
                                if current_route.component.to_lowercase().contains("blog") {
                                    "blog"
                                } else if current_route.component.to_lowercase().contains("recipe")
                                {
                                    "recipes"
                                } else {
                                    "content" // Generic fallback
                                }
                            }
                            .to_string()
                        });

                    #[cfg(target_arch = "wasm32")]
                    web_sys::console::log_1(
                        &format!(
                            "🔍 CONTENT TRANSLATION: Looking for content ID with slug='{}', content_type='{}', language='{}'",
                            current_slug, content_type, current_lang
                        ).into(),
                    );

                    // Use the new content translation system to find the correct slug
                    // First, get the content ID from the current slug
                    if let Some(content_id) =
                        crate::content::item::UnifiedContentItem::get_content_id_from_slug(
                            &current_slug,
                            &content_type,
                            current_lang,
                        )
                    {
                        // Find the translated slug and category using the content ID
                        if let Some((translated_slug, translated_category_opt)) =
                            crate::content::item::UnifiedContentItem::find_translated_content_by_id(
                                &content_id,
                                &content_type,
                                target_language,
                            )
                        {
                            // Build the target URL with the correct translated slug and category
                            let mut target_url = target_route.path.clone();

                            // Replace {slug} with translated slug
                            target_url = target_url.replace("{slug}", &translated_slug);

                            // Replace {category} with translated category (or fallback to original)
                            if target_url.contains("{category}") {
                                let category_to_use = translated_category_opt.as_deref().unwrap_or(&category);
                                target_url = target_url.replace("{category}", category_to_use);
                            }

                            // Remove .html extension from slug if present and add it to the final URL
                            let final_url =
                                if path.ends_with(".html") && !target_url.ends_with(".html") {
                                    format!("{}.html", target_url)
                                } else {
                                    target_url
                                };

                            #[cfg(target_arch = "wasm32")]
                            web_sys::console::log_1(
                                &format!(
                                    "✅ CONTENT TRANSLATION: {} -> {} | ID: {} | Slug: {} -> {} | URL: {} -> {}",
                                    current_lang, target_language, content_id, current_slug, translated_slug, path, final_url
                                ).into()
                            );

                            return Some(final_url);
                        } else {
                            #[cfg(target_arch = "wasm32")]
                            web_sys::console::log_1(
                                &format!(
                                    "⚠️ CONTENT TRANSLATION: No translation found for ID '{}' in language '{}'",
                                    content_id, target_language
                                ).into()
                            );
                        }
                    } else {
                        #[cfg(target_arch = "wasm32")]
                        web_sys::console::log_1(
                            &format!(
                                "⚠️ CONTENT TRANSLATION: No content ID found for slug '{}' in language '{}' content_type '{}'",
                                current_slug, current_lang, content_type
                            ).into()
                        );

                        // Special handling for category-only pages: translate category name if possible
                        if current_slug == category && current_route.path.contains("{category}") && !current_route.path.contains("{slug}") {
                            #[cfg(target_arch = "wasm32")]
                            web_sys::console::log_1(
                                &format!("🏷️ CATEGORY TRANSLATION: Attempting to translate category '{}' from '{}' to '{}'",
                                    category, current_lang, target_language).into()
                            );

                            // Try to find a translated category by looking for any content in the target language
                            // that has posts with the same category in the source language
                            if let Some(translated_category) = find_translated_category_name(&category, &content_type, current_lang, target_language) {
                                let target_url = target_route.path.replace("{category}", &translated_category);

                                #[cfg(target_arch = "wasm32")]
                                web_sys::console::log_1(
                                    &format!(
                                        "✅ CATEGORY TRANSLATION: {} -> {} | Category: {} -> {} | URL: {} -> {}",
                                        current_lang, target_language, category, translated_category, path, target_url
                                    ).into()
                                );

                                return Some(target_url);
                            } else {
                                #[cfg(target_arch = "wasm32")]
                                web_sys::console::log_1(
                                    &format!("⚠️ CATEGORY TRANSLATION: No translation found for category '{}' in language '{}'",
                                        category, target_language).into()
                                );
                            }
                        }

                        // Fallback to old behavior for backward compatibility
                        let target_url = target_route
                            .path
                            .replace("{category}", &category)
                            .replace("{slug}", &current_slug);

                        let final_url = if path.ends_with(".html") && !target_url.ends_with(".html")
                        {
                            format!("{}.html", target_url)
                        } else {
                            target_url
                        };

                        return Some(final_url);
                    }
                }
            }
        }
    }

    None
}

/// Legacy function for backward compatibility
pub fn convert_blog_post_url(
    path: &str,
    current_lang: &str,
    target_language: &str,
) -> Option<String> {
    convert_content_post_url(path, current_lang, target_language)
}

/// Find the translated category name by looking up categories from content index
/// This searches the target language content index for posts that match the source category
fn find_translated_category_name(
    source_category: &str,
    content_type: &str,
    source_lang: &str,
    target_lang: &str
) -> Option<String> {
    // Load the source language content to find content IDs with this category
    let source_items = crate::content::item::UnifiedContentItem::load_for_type(
        content_type,
        source_lang,
    )?;

    // Find any content item that has the source category
    let source_item_with_category = source_items.iter()
        .find(|item| item.categories.contains(&source_category.to_string()))?;

    // Get the content ID for this item
    let content_id = &source_item_with_category.id;

    // Load the target language content and find the same content ID
    let target_items = crate::content::item::UnifiedContentItem::load_for_type(
        content_type,
        target_lang,
    )?;

    // Find the content item with the same ID in the target language
    let target_item = target_items.iter()
        .find(|item| &item.id == content_id)?;

    // Return the translated category (first category from the categories vec)
    target_item.categories.first().cloned()
}

/// Extract category and slug parameters from a content URL
/// Generic function that works with any content type (blog, recipes, etc.)
/// Supports various patterns: {category}, {slug}, {category}/{slug}, post/{slug}, etc.
fn extract_content_params(pattern: &str, url: &str) -> Option<(String, String)> {
    // Remove .html extension for pattern matching
    let clean_url = url.strip_suffix(".html").unwrap_or(url);

    let category_start = pattern.find("{category}");
    let slug_start = pattern.find("{slug}");

    match (category_start, slug_start) {
        // Pattern has both {category} and {slug}
        (Some(cat_start), Some(slug_start)) => {
            extract_category_and_slug_params(pattern, clean_url, cat_start, slug_start)
        },
        // Pattern has only {category}
        (Some(cat_start), None) => {
            extract_category_only_params(pattern, clean_url, cat_start)
        },
        // Pattern has only {slug}
        (None, Some(slug_start)) => {
            extract_slug_only_params(pattern, clean_url, slug_start)
        },
        // Pattern has neither - shouldn't happen
        (None, None) => None,
    }
}

/// Extract both category and slug from patterns like "/recetas/{category}/{slug}"
fn extract_category_and_slug_params(pattern: &str, url: &str, category_start: usize, slug_start: usize) -> Option<(String, String)> {
    // Extract the static parts of the pattern
    let prefix = &pattern[..category_start];
    let middle = &pattern[category_start + 10..slug_start]; // 10 = len("{category}")
    let suffix = &pattern[slug_start + 6..]; // 6 = len("{slug}")

    // Check if URL matches the pattern structure
    if !url.starts_with(prefix) {
        return None;
    }

    let after_prefix = &url[prefix.len()..];
    let middle_pos = after_prefix.find(middle)?;

    // Extract category
    let category = after_prefix[..middle_pos].to_string();

    // Extract slug
    let after_middle = &after_prefix[middle_pos + middle.len()..];
    let slug = if suffix.is_empty() {
        after_middle.to_string()
    } else {
        after_middle.strip_suffix(suffix)?.to_string()
    };

    if category.is_empty() || slug.is_empty() {
        return None;
    }

    Some((category, slug))
}

/// Extract only category from patterns like "/recetas/{category}"
fn extract_category_only_params(pattern: &str, url: &str, category_start: usize) -> Option<(String, String)> {
    let prefix = &pattern[..category_start];
    let suffix = &pattern[category_start + 10..]; // 10 = len("{category}")

    if !url.starts_with(prefix) {
        return None;
    }

    let after_prefix = &url[prefix.len()..];
    let category = if suffix.is_empty() {
        after_prefix.to_string()
    } else {
        after_prefix.strip_suffix(suffix)?.to_string()
    };

    if category.is_empty() {
        return None;
    }

    // For category-only patterns, return category as both category and slug
    // This allows the rest of the logic to work with the existing structure
    Some((category.clone(), category))
}

/// Extract only slug from patterns like "/recetas/post/{slug}"
fn extract_slug_only_params(pattern: &str, url: &str, slug_start: usize) -> Option<(String, String)> {
    let prefix = &pattern[..slug_start];
    let suffix = &pattern[slug_start + 6..]; // 6 = len("{slug}")

    if !url.starts_with(prefix) {
        return None;
    }

    let after_prefix = &url[prefix.len()..];
    let slug = if suffix.is_empty() {
        after_prefix.to_string()
    } else {
        after_prefix.strip_suffix(suffix)?.to_string()
    };

    if slug.is_empty() {
        return None;
    }

    // For slug-only patterns, return slug as both category and slug
    // This allows the rest of the logic to work with the existing structure
    Some((slug.clone(), slug))
}

pub fn get_localized_route(path: &str, target_language: &str) -> String {
    use super::tracker::{get_tracker, NavigationEvent, NavigationEventType};
    use super::cache::cached_route_lookup;

    #[cfg(target_arch = "wasm32")]
    web_sys::console::log_1(
        &format!(
            "🌍 GET_LOCALIZED_ROUTE ENTRY: path='{}', target_language='{}'",
            path, target_language
        ).into(),
    );

    let language_registry = get_language_registry();
    let _default_language = language_registry.get_default_language();
    let (current_lang, _clean_path) = extract_lang_and_path(path);

    // Use cached route lookup to improve performance
    return cached_route_lookup(path, &current_lang, target_language, || {
        get_localized_route_impl(path, target_language)
    });
}

/// Internal implementation of get_localized_route (for caching)
fn get_localized_route_impl(path: &str, target_language: &str) -> String {
    use super::tracker::{get_tracker, NavigationEvent, NavigationEventType};

    #[cfg(not(target_arch = "wasm32"))]
    use std::time::{SystemTime, UNIX_EPOCH};

    #[cfg(not(target_arch = "wasm32"))]
    let start_time = SystemTime::now();
    let language_registry = get_language_registry();
    let default_language = language_registry.get_default_language();
    let (current_lang, clean_path) = extract_lang_and_path(path);

    #[cfg(not(target_arch = "wasm32"))]
    tracing::warn!(
        "🔄 get_localized_route: Converting '{}' from '{}' to '{}' (clean_path: '{}')",
        path, current_lang, target_language, clean_path
    );

    #[cfg(target_arch = "wasm32")]
    web_sys::console::log_1(
        &format!(
            "🔄 WASM get_localized_route: Converting '{}' from '{}' to '{}' (clean_path: '{}')",
            path, current_lang, target_language, clean_path
        ).into(),
    );

    // If already in target language, return as-is
    if current_lang == target_language {
        #[cfg(not(target_arch = "wasm32"))]
        tracing::warn!("✅ get_localized_route: Already in target language, returning '{}'", path);

        // Track this early return (only in non-WASM builds)
        #[cfg(not(target_arch = "wasm32"))]
        if let Some(tracker) = get_tracker() {
            if let Ok(mut tracker) = tracker.lock() {
                let elapsed = start_time.elapsed().unwrap_or_default();
                let mut additional_data = std::collections::HashMap::new();
                additional_data.insert("early_return".to_string(), "same_language".to_string());

                let event = NavigationEvent {
                    session_id: String::new(),
                    timestamp: start_time.duration_since(UNIX_EPOCH).unwrap_or_default().as_millis() as u64,
                    event_type: NavigationEventType::RouteResolution,
                    source_path: path.to_string(),
                    target_path: Some(path.to_string()),
                    current_lang: current_lang.clone(),
                    target_lang: Some(target_language.to_string()),
                    resolution_time_ms: elapsed.as_millis() as u64,
                    cache_hit: true, // Same path is like a cache hit
                    component: None,
                    errors: Vec::new(),
                    fallback_used: false,
                    additional_data,
                };
                tracker.track_event(event);
            }
        }

        return path.to_string();
    }

    // Handle content post URLs with slugs first (before static route mappings)
    if let Some(converted_content_url) =
        convert_content_post_url(path, &current_lang, target_language)
    {
        #[cfg(target_arch = "wasm32")]
        web_sys::console::log_1(
            &format!(
                "✅ ROUTING: Content post URL converted: {} -> {}",
                path, converted_content_url
            )
            .into(),
        );

        // Track content post URL conversion (only in non-WASM builds)
        #[cfg(not(target_arch = "wasm32"))]
        if let Some(tracker) = get_tracker() {
            if let Ok(mut tracker) = tracker.lock() {
                let elapsed = start_time.elapsed().unwrap_or_default();
                let mut additional_data = std::collections::HashMap::new();
                additional_data.insert("conversion_type".to_string(), "content_post_url".to_string());

                let event = NavigationEvent {
                    session_id: String::new(),
                    timestamp: start_time.duration_since(UNIX_EPOCH).unwrap_or_default().as_millis() as u64,
                    event_type: NavigationEventType::RouteResolution,
                    source_path: path.to_string(),
                    target_path: Some(converted_content_url.clone()),
                    current_lang: current_lang.clone(),
                    target_lang: Some(target_language.to_string()),
                    resolution_time_ms: elapsed.as_millis() as u64,
                    cache_hit: false,
                    component: Some("content_post".to_string()),
                    errors: Vec::new(),
                    fallback_used: false,
                    additional_data,
                };
                tracker.track_event(event);
            }
        }

        return converted_content_url;
    }

    // Direct component-based lookup from configuration (most reliable method)
    let config = load_routes_config();

    // First try to find exact route match in current language
    let current_route = config.routes.iter().find(|r| {
        r.enabled && r.language == current_lang && r.path == path
    });

    if let Some(current_route) = current_route {
        #[cfg(not(target_arch = "wasm32"))]
        tracing::warn!(
            "🔍 get_localized_route: Found current route - path: '{}', component: '{}', content_type: {:?}",
            current_route.path, current_route.component, current_route.get_content_type()
        );

        // Look for corresponding route in target language with same component AND content_type if available
        if let Some(target_route) = config.routes.iter().find(|r| {
            r.enabled
            && r.language == target_language
            && r.component == current_route.component
            && r.get_content_type() == current_route.get_content_type()
        }) {
            #[cfg(not(target_arch = "wasm32"))]
            tracing::warn!(
                "✅ get_localized_route: Found target route - path: '{}', component: '{}', content_type: {:?}",
                target_route.path, target_route.component, target_route.get_content_type()
            );
            return target_route.path.clone();
        } else {
            #[cfg(not(target_arch = "wasm32"))]
            tracing::warn!(
                "⚠️ get_localized_route: No target route found for component '{}', content_type: {:?} in language '{}'",
                current_route.component, current_route.get_content_type(), target_language
            );
        }
    } else {
        #[cfg(not(target_arch = "wasm32"))]
        tracing::warn!(
            "⚠️ get_localized_route: No current route found for path '{}' in language '{}'",
            path, current_lang
        );
    }

    // Fallback: Load route mappings from configuration (legacy method)
    let (forward_mappings, reverse_mappings) = build_route_mappings();

    #[cfg(not(target_arch = "wasm32"))]
    tracing::debug!(
        "🔍 get_localized_route: Using mapping fallback - forward_mappings: {:?}, reverse_mappings: {:?}",
        forward_mappings, reverse_mappings
    );

    if target_language == default_language {
        // Convert to default language route
        if let Some(default_path) = reverse_mappings.get(path) {
            #[cfg(not(target_arch = "wasm32"))]
            tracing::debug!("✅ get_localized_route: Found reverse mapping: {} -> {}", path, default_path);
            default_path.clone()
        } else {
            #[cfg(not(target_arch = "wasm32"))]
            tracing::debug!("⚠️ get_localized_route: No reverse mapping, using clean_path: {}", clean_path);
            clean_path // Fallback: return clean path for unmapped routes
        }
    } else {
        // Convert to target language route
        if current_lang == default_language {
            // Direct lookup: default -> target language
            if let Some(target_path) = forward_mappings.get(path) {
                #[cfg(not(target_arch = "wasm32"))]
                tracing::debug!("✅ get_localized_route: Found forward mapping: {} -> {}", path, target_path);
                return target_path.clone();
            }
            #[cfg(not(target_arch = "wasm32"))]
            tracing::warn!("⚠️ get_localized_route: No forward mapping found for: {}", path);
        } else {
            // Two-step conversion: current language -> default -> target language
            if let Some(default_path) = reverse_mappings.get(path) {
                if let Some(target_path) = forward_mappings.get(default_path) {
                    #[cfg(not(target_arch = "wasm32"))]
                    tracing::debug!("✅ get_localized_route: Two-step conversion: {} -> {} -> {}", path, default_path, target_path);
                    return target_path.clone();
                }
            }
        }

        // Handle dynamic routes with slugs using route configuration (language-agnostic)
        for target_route in &config.routes {
            if !target_route.enabled || target_route.language != target_language {
                continue;
            }

            // Look for corresponding route in current language with same component
            if let Some(current_route) = config.routes.iter().find(|r| {
                r.enabled && r.component == target_route.component && r.language == current_lang
            }) {
                // Handle parametric routes with patterns like {category}
                if current_route.path.contains("{") && target_route.path.contains("{") {
                    // Extract the parameter from current path
                    if let Some(start) = current_route.path.find('{') {
                        if let Some(end) = current_route.path.find('}') {
                            let prefix = &current_route.path[..start];
                            let suffix = &current_route.path[end + 1..];

                            if path.starts_with(prefix) && path.ends_with(suffix) {
                                let param_start = prefix.len();
                                let param_end = path.len() - suffix.len();

                                if param_start <= param_end {
                                    let parameter_value = &path[param_start..param_end];

                                    // Extract parameter name from current route pattern
                                    let param_name = &current_route.path[start + 1..end];

                                    // Generate result using target route pattern with the correct parameter name
                                    let target_param_pattern = format!("{{{}}}", param_name);
                                    let result = target_route
                                        .path
                                        .replace(&target_param_pattern, parameter_value);

                                    #[cfg(not(target_arch = "wasm32"))]
                                    tracing::debug!(
                                        "✅ get_localized_route: Dynamic route conversion: {} -> {} ({}) [param: {}={}]",
                                        path, result, target_route.component, param_name, parameter_value
                                    );

                                    return result;
                                }
                            }
                        }
                    }
                }
            }
        }

        // Final fallback: Look for any route in target language with matching canonical_path
        if let Some(canonical_route) = config.routes.iter().find(|r| {
            r.enabled
                && r.language == target_language
                && r.canonical_path
                    .as_ref()
                    .map_or(false, |cp| cp == &clean_path)
        }) {
            #[cfg(not(target_arch = "wasm32"))]
            tracing::debug!(
                "✅ get_localized_route: Canonical path fallback: {} -> {}",
                path, canonical_route.path
            );
            return canonical_route.path.clone();
        }

        // Ultimate fallback: return original path unchanged
        #[cfg(not(target_arch = "wasm32"))]
        tracing::warn!(
            "⚠️ get_localized_route: No route mapping found for {} -> {} language, keeping original",
            path, target_language
        );

        let result = path.to_string();

        // Track the route resolution event (only in non-WASM builds)
        #[cfg(not(target_arch = "wasm32"))]
        if let Some(tracker) = get_tracker() {
            if let Ok(mut tracker) = tracker.lock() {
                let elapsed = start_time.elapsed().unwrap_or_default();
                let mut additional_data = std::collections::HashMap::new();
                additional_data.insert("clean_path".to_string(), clean_path.clone());
                additional_data.insert("fallback_used".to_string(), "true".to_string());
                additional_data.insert("fallback_type".to_string(), "ultimate_fallback".to_string());

                let event = NavigationEvent {
                    session_id: String::new(), // Will be set by tracker
                    timestamp: start_time
                        .duration_since(UNIX_EPOCH)
                        .unwrap_or_default()
                        .as_millis() as u64,
                    event_type: NavigationEventType::RouteResolution,
                    source_path: path.to_string(),
                    target_path: Some(result.clone()),
                    current_lang: current_lang.clone(),
                    target_lang: Some(target_language.to_string()),
                    resolution_time_ms: elapsed.as_millis() as u64,
                    cache_hit: false,
                    component: None,
                    errors: Vec::new(),
                    fallback_used: true,
                    additional_data,
                };
                tracker.track_event(event);
            }
        }

        result
    }
}

/// Route information structure
#[derive(Debug, Clone)]
pub struct RouteInfo {
    pub path: String,
    pub language: String,
    pub clean_path: String,
    pub is_default_language: bool,
}

impl RouteInfo {
    /// Create RouteInfo from a path
    pub fn from_path(path: &str) -> Self {
        let language_registry = get_language_registry();
        let default_language = language_registry.get_default_language();
        let (language, clean_path) = extract_lang_and_path(path);
        let is_default_language = language == default_language;

        Self {
            path: path.to_string(),
            language,
            clean_path,
            is_default_language,
        }
    }

    /// Get alternate language version of this route
    pub fn get_alternate(&self, target_language: &str) -> String {
        get_localized_route(&self.path, target_language)
    }
}

/// Validate route format
pub fn is_valid_route_format(path: &str) -> bool {
    // Basic validation - starts with /, no double slashes, no query params for now
    path.starts_with('/') && !path.contains("//") && !path.contains('?')
}

/// Check if a route is language-specific (localized path, not /lang/ prefix format)
pub fn is_lang_specific_route(path: &str, lang: &str) -> bool {
    let config = load_routes_config();
    let language_registry = get_language_registry();
    let default_language = language_registry.get_default_language();

    // Check if this path exists in the configuration for the specified language
    // and is NOT in the /lang/... prefix format AND is NOT the default language
    config.routes.iter().any(|route| {
        route.enabled
            && (route.path == path || path_matches_pattern(&route.path, path))
            && route.language == lang
            && lang != default_language
            && !path.starts_with(&format!("/{lang}/"))
    })
}

/// Check if a path matches a route pattern (supports {param} placeholders)
fn path_matches_pattern(pattern: &str, actual_path: &str) -> bool {
    // Simple pattern matching for {category}, {slug} etc.
    let pattern_parts: Vec<&str> = pattern.split('/').collect();
    let path_parts: Vec<&str> = actual_path.split('/').collect();

    if pattern_parts.len() != path_parts.len() {
        return false;
    }

    for (pattern_part, path_part) in pattern_parts.iter().zip(path_parts.iter()) {
        if pattern_part.starts_with('{') && pattern_part.ends_with('}') {
            // This is a parameter placeholder - it matches any value
            continue;
        } else if pattern_part != path_part {
            return false;
        }
    }

    true
}

/// Generate sitemap entry data
#[derive(Debug, Clone, PartialEq)]
pub struct SitemapEntry {
    pub url: String,
    pub language: String,
    pub alternate_urls: Vec<AlternateUrl>,
    pub last_modified: Option<String>,
    pub priority: f32,
}

/// Alternate URL for sitemap
#[derive(Debug, Clone, PartialEq)]
pub struct AlternateUrl {
    pub language: String,
    pub url: String,
}

/// Generate sitemap data for all available routes
pub fn generate_sitemap_data(base_url: &str) -> Vec<SitemapEntry> {
    let config = load_routes_config();
    let language_registry = get_language_registry();
    let _available_languages = language_registry.get_available_languages();
    let mut entries = Vec::new();

    // Group routes by component to create alternate language entries
    let mut routes_by_component: HashMap<String, HashMap<String, &RouteConfigToml>> =
        HashMap::new();

    for route in &config.routes {
        if !route.enabled || !route.is_visible_in_sitemap() {
            continue;
        }

        routes_by_component
            .entry(route.component.clone())
            .or_default()
            .insert(route.language.clone(), route);
    }

    // Generate sitemap entries with alternates
    for (_, lang_routes) in routes_by_component {
        for (language, route) in &lang_routes {
            let url = if route.path == "/" {
                if language == language_registry.get_default_language() {
                    base_url.to_string()
                } else {
                    format!("{base_url}/{language}")
                }
            } else if language == language_registry.get_default_language() {
                format!("{base_url}{}", route.path)
            } else if route.path.starts_with(&format!("/{language}/")) {
                format!("{base_url}{}", route.path)
            } else {
                format!("{base_url}/{language}{}", route.path)
            };

            let mut alternate_urls = Vec::new();
            for (alt_lang, alt_route) in &lang_routes {
                let alt_url = if alt_route.path == "/" {
                    if alt_lang == language_registry.get_default_language() {
                        base_url.to_string()
                    } else {
                        format!("{base_url}/{alt_lang}")
                    }
                } else if alt_lang == language_registry.get_default_language() {
                    format!("{base_url}{}", alt_route.path)
                } else if alt_route.path.starts_with(&format!("/{alt_lang}/")) {
                    format!("{base_url}{}", alt_route.path)
                } else {
                    format!("{base_url}/{alt_lang}{}", alt_route.path)
                };

                alternate_urls.push(AlternateUrl {
                    language: alt_lang.clone(),
                    url: alt_url,
                });
            }

            entries.push(SitemapEntry {
                url,
                language: language.clone(),
                alternate_urls,
                last_modified: None,
                priority: route.get_priority(),
            });
        }
    }

    entries
}

/// Generate robots.txt content
pub fn generate_robots_txt(base_url: &str) -> String {
    format!(
        "User-agent: *\nAllow: /\n\nSitemap: {}/sitemap.xml\n",
        base_url.trim_end_matches('/')
    )
}

/// Generate breadcrumb data for a given path
pub fn get_breadcrumbs(path: &str, base_url: &str) -> Vec<BreadcrumbItem> {
    let _language_registry = get_language_registry();
    let (language, clean_path) = extract_lang_and_path(path);
    let mut breadcrumbs = Vec::new();

    // Always add home
    let home_title = get_breadcrumb_title("home", &language);
    let home_url = get_canonical_url("/", &language, base_url);

    breadcrumbs.push(BreadcrumbItem {
        title: home_title,
        url: home_url,
        is_current: clean_path == "/",
    });

    // Add intermediate paths
    if clean_path != "/" {
        let parts: Vec<&str> = clean_path
            .trim_start_matches('/')
            .split('/')
            .filter(|p| !p.is_empty())
            .collect();
        let mut current_path = String::new();

        for (i, part) in parts.iter().enumerate() {
            current_path.push('/');
            current_path.push_str(part);

            let is_current = i == parts.len() - 1;
            let title = get_breadcrumb_title(part, &language);
            let url = get_canonical_url(&current_path, &language, base_url);

            breadcrumbs.push(BreadcrumbItem {
                title,
                url,
                is_current,
            });
        }
    }

    breadcrumbs
}

/// Breadcrumb item structure
#[derive(Debug, Clone)]
pub struct BreadcrumbItem {
    pub title: String,
    pub url: String,
    pub is_current: bool,
}

/// Get breadcrumb title for a path segment (language-agnostic using i18n system)
fn get_breadcrumb_title(segment: &str, language: &str) -> String {
    // Use the i18n system to get proper translations for breadcrumb titles
    let breadcrumb_key = format!("breadcrumb-{}", segment);

    // Try to get translation from i18n system
    let translation = crate::i18n::t_for_language(language, &breadcrumb_key);

    // If translation is the same as key (meaning not found), use fallback
    if translation == breadcrumb_key {
        // Fallback: capitalize first letter of segment
        let mut chars: Vec<char> = segment.chars().collect();
        if !chars.is_empty() {
            chars[0] = chars[0].to_uppercase().next().unwrap_or(chars[0]);
            chars.into_iter().collect()
        } else {
            segment.to_string()
        }
    } else {
        translation
    }
}

/// Convenience functions for common routing operations
/// Handle a route and return metadata
pub fn handle_route_metadata(path: &str, base_url: &str) -> super::defs::RouteMetadata {
    use super::engine::resolve_route;

    let resolved = resolve_route(path);
    let _canonical_url = get_canonical_url(path, &resolved.language, base_url);

    super::defs::RouteMetadata::new(path, &resolved.language)
        .with_title(&format!("Page - {path}"))
        .with_description("Page description")
        .with_keywords(vec!["rust", "developer", "infrastructure"])
}

/// Quick route validation
pub fn validate_route(path: &str) -> bool {
    use super::engine::is_valid_route;
    is_valid_route(path)
}

/// Get the language-specific home URL
pub fn get_home_url_for_language(language: &str) -> String {
    let language_registry = get_language_registry();
    let default_language = language_registry.get_default_language();

    if language == default_language {
        "/".to_string()
    } else {
        format!("/{language}")
    }
}

/// Get navigation data for a path
pub fn get_navigation_data(path: &str, base_url: &str) -> super::defs::NavigationData {
    use super::engine::resolve_route;

    let resolved = resolve_route(path);
    let breadcrumbs = get_breadcrumbs(path, base_url);

    super::defs::NavigationData {
        current_path: path.to_string(),
        language: resolved.language,
        breadcrumbs,
        is_not_found: resolved.component.is_none(),
    }
}
