//! Internationalization (i18n) module using modern pattern-based FTL loading
//!
//! This module provides a complete i18n solution that works both on the server
//! and client (WASM) by using dynamic language discovery and the modern FTL
//! content loader system.

use std::collections::HashMap;

/// Get supported languages dynamically from filesystem discovery
pub fn get_supported_languages() -> &'static Vec<String> {
    crate::i18n::discovery::discover_available_languages()
}

/// Get default language dynamically from filesystem discovery
pub fn get_default_language() -> &'static str {
    crate::i18n::discovery::get_default_language()
}

/// Check if a language is supported
pub fn is_supported_language(lang: &str) -> bool {
    crate::i18n::discovery::is_supported_language(lang)
}

// Language identifiers removed - no longer needed with modern FTL system

/// Error types for i18n operations
#[derive(Debug, thiserror::Error)]
pub enum I18nError {
    #[error("FTL resource loading error: {0}")]
    ContentLoadError(String),
    #[error("Language '{0}' not supported")]
    UnsupportedLanguage(String),
    #[error("Translation key '{key}' not found for language '{lang}'")]
    KeyNotFound { key: String, lang: String },
}

// Deprecated I18n struct and implementation removed - migration to
// pattern-based system complete

/// Simple convenience function for quick translations using modern FTL system
pub fn t(key: &str) -> String {
    t_for_language(get_default_language(), key)
}

/// Quick translation function for specific language with hydration safety
/// Uses the FTL_REGISTRY (populated at startup) with filesystem fallback.
pub fn t_for_language(language: &str, key: &str) -> String {
    // Use thread_local to cache loaded translations
    thread_local! {
        static CACHED_TRANSLATIONS: std::cell::RefCell<HashMap<String, std::collections::HashMap<String, String>>> = std::cell::RefCell::new(HashMap::new());
    }

    CACHED_TRANSLATIONS.with(|cache| {
        let mut cache_ref = cache.borrow_mut();

        // Load translations for this language if not cached
        if !cache_ref.contains_key(language) {
            // Primary: read from FTL_REGISTRY populated by register_contributor at startup
            if let Some(lang_map) = crate::registration::get_parsed_ftl_for_language(language) {
                if !lang_map.is_empty() {
                    cache_ref.insert(language.to_string(), lang_map);
                }
            }
            // Fallback: filesystem loader (for standalone/test contexts without a registry)
            if !cache_ref.contains_key(language) {
                match crate::fluent::content_loader::load_texts_from_ftl(language) {
                    Ok(texts) => {
                        let lang_map = texts.get_translations_for_language(language);
                        cache_ref.insert(language.to_string(), lang_map);
                    }
                    Err(_) => {
                        cache_ref.insert(language.to_string(), std::collections::HashMap::new());
                    }
                }
            }
        }

        if let Some(translations) = cache_ref.get(language) {
            translations.get(key).cloned().unwrap_or_else(|| {
                // More specific fallback based on key and language
                match (key, language) {
                    ("subscription-form-description", "es") => "Mantente actualizado con nuestras \
                                                                últimas noticias y actualizaciones"
                        .to_string(),
                    ("subscription-form-description", _) => {
                        "Stay updated with our latest news and updates".to_string()
                    }
                    _ => format!("[{key}]"),
                }
            })
        } else {
            format!("[{key}]")
        }
    })
}

/// Utility functions for common translation patterns
pub mod util {
    use super::*;

    /// Create fluent arguments from key-value pairs
    pub fn args<'a>(pairs: &[(&'a str, &'a str)]) -> fluent::FluentArgs<'a> {
        let mut args = fluent::FluentArgs::new();
        for (key, value) in pairs {
            args.set(*key, fluent::FluentValue::from(*value));
        }
        args
    }

    /// Create fluent arguments with numbers
    pub fn args_with_number<'a>(pairs: &[(&'a str, f64)]) -> fluent::FluentArgs<'a> {
        let mut args = fluent::FluentArgs::new();
        for (key, value) in pairs {
            args.set(*key, fluent::FluentValue::from(*value));
        }
        args
    }

    /// Get a localized page title
    pub fn page_title(page: &str) -> String {
        let key = format!("page-{page}-title");
        t(&key)
    }

    /// Get a localized navigation label
    pub fn nav_label(page: &str) -> String {
        t(page)
    }

    /// Get a localized button text
    pub fn button_text(action: &str) -> String {
        let key = format!("button-{action}");
        t(&key)
    }

    /// Get a localized form label
    pub fn form_label(field: &str) -> String {
        let key = format!("form-{field}");
        t(&key)
    }

    /// Get a localized error message
    pub fn error_message(error_type: &str) -> String {
        let key = format!("error-{error_type}");
        t(&key)
    }
}

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

    #[test]
    fn test_language_support() {
        let supported = get_supported_languages();
        assert!(!supported.is_empty());

        let default = get_default_language();
        assert!(!default.is_empty());
        assert!(is_supported_language(default));
    }

    #[test]
    fn test_convenience_functions() {
        // Test that convenience functions don't panic with modern FTL system
        let _translation = t("common-home");
        let _translation_es = t_for_language("es", "common-home");
    }

    #[test]
    fn test_modern_translation_system() {
        // Test the modern translation system returns proper fallback for missing keys
        let missing_key = t_for_language("en", "nonexistent-key");
        assert!(missing_key.starts_with('[') && missing_key.ends_with(']'));

        let missing_es = t_for_language("es", "nonexistent-key");
        assert!(missing_es.starts_with('[') && missing_es.ends_with(']'));
    }
}
