use es_fluent::{EsFluent, ToFluentString}; // Import ToFluentString trait

trait HasLen {
    fn len(&self) -> usize;
}

impl<T> HasLen for Vec<T> {
    fn len(&self) -> usize {
        self.len()
    }
}
impl HasLen for String {
    fn len(&self) -> usize {
        self.len()
    }
}

// Add trait bound so that x.len() is valid in the closure
#[derive(EsFluent)]
#[fluent(derive(Debug, Clone))]
struct LenValidation<T: HasLen> {
    min: usize,
    max: usize,
    // Explicit type required for generic inference in this context
    #[fluent(value(|x: &T| x.len()))]
    actual: T,
}

#[derive(EsFluent)]
struct StringBox {
    // Explicit type helper
    #[fluent(value(|x: &String| x.len()))]
    value: String,
}

#[test]
fn test_len_validation() {
    let val = LenValidation {
        min: 1,
        max: 5,
        actual: vec![1, 2, 3],
    };

    // Use to_fluent_string() which is generated by derive
    // This calls fluent_fmt which calls our closure.
    // If this runs without panic (and returns valid string, usually key name if no bundle), it verifies logic compilation.
    let s = val.to_fluent_string();
    println!("Result: {}", s);
}

#[test]
fn test_string_box() {
    let val = StringBox {
        value: "hello".to_string(),
    };
    let s = val.to_fluent_string();
    println!("Result: {}", s);
}

#[derive(EsFluent)]
enum EnumLenValidation<T: HasLen> {
    Tuple(#[fluent(value(|x: &T| x.len()))] T),
    Struct {
        #[fluent(value(|x: &T| x.len()))]
        val: T,
    },
}

#[test]
fn test_enum_len_validation() {
    let t = EnumLenValidation::Tuple(vec![1, 2]);
    let _ = t.to_fluent_string();

    let s = EnumLenValidation::Struct { val: vec![1, 2, 3] };
    let _ = s.to_fluent_string();
}
