//! Custom Minijinja filters bridging templates to the framework's Fluent
//! i18n bundle and other utilities.
//!
//! Use [`register_filters`] to install all filters onto an [`Environment`]
//! before rendering. The same closure is wired up by
//! [`super::engine::TemplateEngine::with_setup`] so dev autoreload also
//! re-registers them after every rebuild.

use minijinja::Environment;

use crate::templating::engine::TemplateError;

/// Registers every framework-provided filter into the environment.
///
/// Filters installed:
/// - `fluent(lang)`: looks up the value by key in the active language bundle.
pub fn register_filters(env: &mut Environment<'static>) -> Result<(), TemplateError> {
    env.add_filter("fluent", fluent_filter);
    Ok(())
}

/// `{{ "page.title" | fluent("es") }}` — resolves `key` against the Fluent
/// bundle for `lang`. When `lang` is `None`, falls back to the project's
/// default language.
fn fluent_filter(key: String, lang: Option<String>) -> String {
    let language =
        lang.unwrap_or_else(|| rustelo_core_lib::config::get_default_language().to_string());
    rustelo_core_lib::i18n::t_for_language(&language, &key)
}

#[cfg(test)]
mod tests {
    use minijinja::context;

    use super::*;

    #[test]
    fn fluent_filter_returns_key_when_no_bundle_loaded() {
        // Without Fluent bundles loaded, `t_for_language` typically returns the key
        // verbatim. The contract we exercise here is that the filter does not panic
        // and produces a String — bundle loading is covered by integration tests.
        let value = fluent_filter("page.title".to_string(), Some("en".to_string()));
        assert!(!value.is_empty());
    }

    #[test]
    fn renders_filter_in_template() {
        let mut env = Environment::new();
        register_filters(&mut env).expect("register");
        env.add_template("t.html", r#"{{ "page.title" | fluent("en") }}"#)
            .expect("template");
        let out = env
            .get_template("t.html")
            .expect("template just added must be retrievable")
            .render(context! {})
            .expect("render");
        assert!(!out.is_empty());
    }

    #[test]
    fn defaults_lang_when_omitted() {
        let mut env = Environment::new();
        register_filters(&mut env).expect("register");
        env.add_template("t.html", r#"{{ "page.title" | fluent }}"#)
            .expect("template");
        let out = env
            .get_template("t.html")
            .expect("template just added must be retrievable")
            .render(context! {})
            .expect("render");
        assert!(!out.is_empty());
    }
}
