use proptest::{
    prelude::*,
    strategy::BoxedStrategy,
};

use crate::syntax::{
    lexer::{
        Lexer,
        Token,
    },
    FileParser,
};

// ===== Generators for valid syntax elements =====

fn valid_ident() -> impl Strategy<Value = String> {
    "[a-zA-Z_][a-zA-Z0-9_]{0,20}".prop_filter("not a keyword", |s| {
        !matches!(
            s.as_str(),
            "use" |
                "character" |
                "template" |
                "life_arc" |
                "schedule" |
                "behavior" |
                "institution" |
                "relationship" |
                "location" |
                "species" |
                "enum" |
                "state" |
                "on" |
                "as" |
                "self" |
                "other" |
                "remove" |
                "append" |
                "forall" |
                "exists" |
                "in" |
                "where" |
                "and" |
                "or" |
                "not" |
                "is" |
                "true" |
                "false" |
                // Behavior tree keywords
                "if" |
                "when" |
                "choose" |
                "then" |
                "include" |
                "repeat" |
                "invert" |
                "retry" |
                "timeout" |
                "cooldown" |
                "succeed_always" |
                "fail_always" |
                // Type system keywords (v0.3.0)
                "concept" |
                "sub_concept" |
                "definition" |
                "any"
        )
    })
}

fn valid_string() -> impl Strategy<Value = String> {
    // Strings without quotes or backslashes for simplicity
    "[a-zA-Z0-9 ,.!?-]{0,50}"
}

fn valid_int() -> impl Strategy<Value = i64> {
    -1000i64..1000i64
}

fn valid_float() -> impl Strategy<Value = f64> {
    (-1000.0..1000.0).prop_filter("finite", |f: &f64| f.is_finite())
}

fn valid_time() -> impl Strategy<Value = (u8, u8, u8)> {
    (0u8..24, 0u8..60, 0u8..60)
}

fn valid_duration() -> impl Strategy<Value = (u32, u32, u32)> {
    (0u32..24, 0u32..60, 0u32..60)
}

// ===== Lexer property tests =====

proptest! {
    #[test]
    fn test_lexer_doesnt_panic(s in "\\PC{0,100}") {
        // Any string should not panic the lexer
        let lexer = Lexer::new(&s);
        let _tokens: Vec<_> = lexer.collect();
    }

    #[test]
    fn test_valid_ident_tokenizes(name in valid_ident()) {
        let lexer = Lexer::new(&name);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        match &tokens[0] {
            Token::Ident(s) => assert_eq!(s, &name),
            _ => panic!("Expected Ident token, got {:?}", tokens[0]),
        }
    }

    #[test]
    fn test_valid_int_tokenizes(n in valid_int()) {
        let input = n.to_string();
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        match tokens[0] {
            Token::NumberLit(val) => assert_eq!(val, n),
            _ => panic!("Expected NumberLit token"),
        }
    }

    #[test]
    fn test_valid_float_tokenizes(n in valid_float()) {
        let input = format!("{:.2}", n);
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        match tokens[0] {
            Token::DecimalLit(_) => {},
            _ => panic!("Expected DecimalLit token"),
        }
    }

    #[test]
    fn test_valid_string_tokenizes(s in valid_string()) {
        let input = format!("\"{}\"", s);
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        match &tokens[0] {
            Token::TextLit(val) => assert_eq!(val, &s),
            _ => panic!("Expected TextLit token"),
        }
    }

    #[test]
    fn test_time_literal_tokenizes(time in valid_time()) {
        let (h, m, s) = time;
        let input = format!("{:02}:{:02}:{:02}", h, m, s);
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        match &tokens[0] {
            Token::TimeLit(_) => {},
            _ => panic!("Expected TimeLit token"),
        }
    }

    #[test]
    fn test_duration_literal_tokenizes(dur in valid_duration()) {
        let (h, m, s) = dur;
        let input = if h > 0 && m > 0 && s > 0 {
            format!("{}h{}m{}s", h, m, s)
        } else if h > 0 && m > 0 {
            format!("{}h{}m", h, m)
        } else if h > 0 {
            format!("{}h", h)
        } else if m > 0 {
            format!("{}m", m)
        } else {
            format!("{}s", s)
        };

        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();

        if !input.is_empty() && input != "0h" && input != "0m" && input != "0s" {
            assert!(!tokens.is_empty(), "Duration '{}' should tokenize", input);
        }
    }

    #[test]
    fn test_keywords_are_distinct_from_idents(
        keyword in prop::sample::select(vec![
            "character", "template", "use", "self", "other",
            "and", "or", "not", "is", "true", "false",
            "if", "when", "choose", "then", "include"
        ])
    ) {
        let lexer = Lexer::new(keyword);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 1);
        // Should be a keyword token, not Ident
        if let Token::Ident(_) = &tokens[0] { panic!("'{}' should be a keyword, not an Ident", keyword) }
    }

    #[test]
    fn test_whitespace_separates_tokens(
        name1 in valid_ident(),
        name2 in valid_ident(),
        ws in "[ \t\n]{1,5}"
    ) {
        let input = format!("{}{}{}", name1, ws, name2);
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();
        assert_eq!(tokens.len(), 2);
        match (&tokens[0], &tokens[1]) {
            (Token::Ident(s1), Token::Ident(s2)) => {
                assert_eq!(s1, &name1);
                assert_eq!(s2, &name2);
            }
            _ => panic!("Expected two Ident tokens"),
        }
    }
}

// ===== Parser property tests =====

fn valid_field() -> impl Strategy<Value = (String, String)> {
    (valid_ident(), valid_int().prop_map(|n| n.to_string()))
}

fn valid_character() -> impl Strategy<Value = String> {
    (valid_ident(), prop::collection::vec(valid_field(), 0..5)).prop_map(|(name, fields)| {
        let fields_str = fields
            .iter()
            .map(|(k, v)| format!("    {}: {}", k, v))
            .collect::<Vec<_>>()
            .join("\n");
        format!("character {} {{\n{}\n}}", name, fields_str)
    })
}

fn valid_template() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop::collection::vec(
            (valid_ident(), valid_int(), valid_int()).prop_map(|(name, lo, hi)| {
                let (min, max) = if lo < hi { (lo, hi) } else { (hi, lo) };
                (name, format!("{}..{}", min, max))
            }),
            0..5,
        ),
    )
        .prop_map(|(name, fields)| {
            let fields_str = fields
                .iter()
                .map(|(k, v)| format!("    {}: {}", k, v))
                .collect::<Vec<_>>()
                .join("\n");
            format!("template {} {{\n{}\n}}", name, fields_str)
        })
}

fn valid_schedule() -> impl Strategy<Value = String> {
    (valid_ident(), prop::collection::vec(valid_time(), 1..5)).prop_map(|(name, times)| {
        let blocks = times
            .windows(2)
            .map(|w| {
                let (h1, m1, s1) = w[0];
                let (h2, m2, _) = w[1];
                format!(
                    "    {:02}:{:02}:{:02} -> {:02}:{:02}:00: activity {{ }}",
                    h1, m1, s1, h2, m2
                )
            })
            .collect::<Vec<_>>()
            .join("\n");
        format!("schedule {} {{\n{}\n}}", name, blocks)
    })
}

fn valid_location() -> impl Strategy<Value = String> {
    (valid_ident(), prop::collection::vec(valid_field(), 0..5)).prop_map(|(name, fields)| {
        let fields_str = fields
            .iter()
            .map(|(k, v)| format!("    {}: {}", k, v))
            .collect::<Vec<_>>()
            .join("\n");
        format!("location {} {{\n{}\n}}", name, fields_str)
    })
}

fn valid_species() -> impl Strategy<Value = String> {
    (valid_ident(), prop::collection::vec(valid_field(), 0..5)).prop_map(|(name, fields)| {
        let fields_str = fields
            .iter()
            .map(|(k, v)| format!("    {}: {}", k, v))
            .collect::<Vec<_>>()
            .join("\n");
        format!("species {} {{\n{}\n}}", name, fields_str)
    })
}

fn valid_institution() -> impl Strategy<Value = String> {
    (valid_ident(), prop::collection::vec(valid_field(), 0..5)).prop_map(|(name, fields)| {
        let fields_str = fields
            .iter()
            .map(|(k, v)| format!("    {}: {}", k, v))
            .collect::<Vec<_>>()
            .join("\n");
        format!("institution {} {{\n{}\n}}", name, fields_str)
    })
}

fn valid_relationship() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        valid_ident(),
        valid_ident(),
        prop::collection::vec(valid_field(), 0..3),
    )
        .prop_map(|(name, person1, person2, fields)| {
            let fields_str = fields
                .iter()
                .map(|(k, v)| format!("    {}: {}", k, v))
                .collect::<Vec<_>>()
                .join("\n");
            format!(
                "relationship {} {{\n    {} {{ }}\n    {} {{ }}\n{}\n}}",
                name, person1, person2, fields_str
            )
        })
}

proptest! {
    #[test]
    fn test_parser_doesnt_panic(input in "\\PC{0,200}") {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let _ = parser.parse(lexer);
        // Should not panic
    }

    #[test]
    fn test_valid_character_parses(input in valid_character()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid character: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Character(_) => {},
                _ => panic!("Expected Character declaration"),
            }
        }
    }

    #[test]
    fn test_valid_template_parses(input in valid_template()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid template: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Template(_) => {},
                _ => panic!("Expected Template declaration"),
            }
        }
    }

    #[test]
    fn test_valid_schedule_parses(input in valid_schedule()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid schedule: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Schedule(_) => {},
                _ => panic!("Expected Schedule declaration"),
            }
        }
    }

    #[test]
    fn test_valid_location_parses(input in valid_location()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid location: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Location(_) => {},
                _ => panic!("Expected Location declaration"),
            }
        }
    }

    #[test]
    fn test_valid_species_parses(input in valid_species()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid species: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Species(_) => {},
                _ => panic!("Expected Species declaration"),
            }
        }
    }

    #[test]
    fn test_valid_institution_parses(input in valid_institution()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid institution: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Institution(_) => {},
                _ => panic!("Expected Institution declaration"),
            }
        }
    }

    #[test]
    fn test_valid_relationship_parses(input in valid_relationship()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid relationship: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Relationship(_) => {},
                _ => panic!("Expected Relationship declaration"),
            }
        }
    }

    #[test]
    fn test_multiple_declarations_parse(
        chars in prop::collection::vec(valid_character(), 0..3),
        templates in prop::collection::vec(valid_template(), 0..3),
    ) {
        let mut all = chars;
        all.extend(templates);
        let input = all.join("\n\n");

        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);

        if !all.is_empty() {
            assert!(result.is_ok(), "Failed to parse multiple declarations:\n{}\nError: {:?}", input, result.err());
            if let Ok(file) = result {
                assert_eq!(file.declarations.len(), all.len());
            }
        }
    }
}

// ===== Life Arc generators =====

fn valid_comparison_expr() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop::sample::select(vec![">", ">=", "<", "<="]),
        prop_oneof![
            valid_int().prop_map(|n| n.to_string()),
            valid_float().prop_map(|f| format!("{:.2}", f)),
        ],
    )
        .prop_map(|(ident, op, val)| format!("{} {} {}", ident, op, val))
}

fn valid_equality_expr() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop_oneof![
            valid_int().prop_map(|n| n.to_string()),
            valid_float().prop_map(|f| format!("{:.2}", f)),
            valid_string().prop_map(|s| format!("\"{}\"", s)),
            Just("true".to_string()),
            Just("false".to_string()),
        ],
    )
        .prop_map(|(ident, val)| format!("{} is {}", ident, val))
}

fn valid_logical_and_expr() -> impl Strategy<Value = String> {
    (valid_comparison_expr(), valid_comparison_expr())
        .prop_map(|(left, right)| format!("{} and {}", left, right))
}

fn valid_logical_or_expr() -> impl Strategy<Value = String> {
    (valid_ident(), valid_ident()).prop_map(|(left, right)| format!("{} or {}", left, right))
}

fn valid_logical_not_expr() -> impl Strategy<Value = String> {
    valid_ident().prop_map(|ident| format!("not {}", ident))
}

fn valid_field_access_expr() -> impl Strategy<Value = String> {
    (prop::sample::select(vec!["self", "other"]), valid_ident())
        .prop_map(|(base, field)| format!("{}.{}", base, field))
}

fn valid_field_access_comparison() -> impl Strategy<Value = String> {
    (
        valid_field_access_expr(),
        prop::sample::select(vec![">", ">=", "<", "<="]),
        prop_oneof![valid_int().prop_map(|n| n.to_string()), valid_ident(),],
    )
        .prop_map(|(field, op, val)| format!("{} {} {}", field, op, val))
}

fn valid_transition_condition() -> impl Strategy<Value = String> {
    prop_oneof![
        valid_ident(),                           // Simple identifier
        valid_int().prop_map(|n| n.to_string()), // Literal int
        Just("true".to_string()),                // Boolean literal
        Just("false".to_string()),
        valid_comparison_expr(),         // Comparison expression
        valid_equality_expr(),           // Equality expression
        valid_logical_and_expr(),        // Logical AND
        valid_logical_or_expr(),         // Logical OR
        valid_logical_not_expr(),        // Logical NOT
        valid_field_access_expr(),       // Field access
        valid_field_access_comparison(), // Field access with comparison
    ]
}

fn valid_transition() -> impl Strategy<Value = String> {
    (valid_transition_condition(), valid_ident())
        .prop_map(|(cond, target)| format!("        on {} -> {}", cond, target))
}

fn valid_arc_state() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop::collection::vec(valid_transition(), 0..3),
    )
        .prop_map(|(state_name, transitions)| {
            let trans_str = transitions.join("\n");
            if transitions.is_empty() {
                format!("    state {} {{}}", state_name)
            } else {
                format!("    state {} {{\n{}\n    }}", state_name, trans_str)
            }
        })
}

fn valid_life_arc() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop::collection::vec(valid_arc_state(), 1..5),
    )
        .prop_map(|(name, states)| {
            let states_str = states.join("\n");
            format!("life_arc {} {{\n{}\n}}", name, states_str)
        })
}

// ===== Behavior Tree generators =====

fn valid_action_node() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        prop::option::of(prop::collection::vec(valid_field(), 0..3)),
    )
        .prop_map(|(name, params)| match params {
            | None => name,
            | Some(params) if params.is_empty() => format!("{}()", name),
            | Some(params) => {
                let params_str = params
                    .iter()
                    .map(|(k, v)| format!("{}: {}", k, v))
                    .collect::<Vec<_>>()
                    .join(", ");
                format!("{}({})", name, params_str)
            },
        })
}

fn valid_behavior_node_depth(depth: u32) -> BoxedStrategy<String> {
    if depth == 0 {
        // Base case: just actions or subtrees
        prop_oneof![
            valid_action_node(),
            valid_ident().prop_map(|name| format!("include {}", name)),
        ]
        .boxed()
    } else {
        // Recursive case: can be action, subtree, selector, or sequence
        let action = valid_action_node();
        let subtree = valid_ident().prop_map(|name| format!("include {}", name));

        let selector = prop::collection::vec(valid_behavior_node_depth(depth - 1), 1..3).prop_map(
            |children| {
                let children_str = children
                    .iter()
                    .map(|c| format!("        {}", c))
                    .collect::<Vec<_>>()
                    .join("\n");
                format!("choose {{\n{}\n    }}", children_str)
            },
        );

        let sequence = prop::collection::vec(valid_behavior_node_depth(depth - 1), 1..3).prop_map(
            |children| {
                let children_str = children
                    .iter()
                    .map(|c| format!("        {}", c))
                    .collect::<Vec<_>>()
                    .join("\n");
                format!("then {{\n{}\n    }}", children_str)
            },
        );

        prop_oneof![action, subtree, selector, sequence,].boxed()
    }
}

fn valid_behavior_tree() -> impl Strategy<Value = String> {
    (
        valid_ident(),
        valid_behavior_node_depth(2), // Max depth 2 to keep tests fast
    )
        .prop_map(|(name, root)| format!("behavior {} {{\n    {}\n}}", name, root))
}

proptest! {
    #[test]
    fn test_valid_life_arc_parses(input in valid_life_arc()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid life_arc: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::LifeArc(_) => {},
                _ => panic!("Expected LifeArc declaration"),
            }
        }
    }

    #[test]
    fn test_valid_behavior_tree_parses(input in valid_behavior_tree()) {
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse valid behavior: {}\nError: {:?}", input, result.err());

        if let Ok(file) = result {
            assert_eq!(file.declarations.len(), 1);
            match &file.declarations[0] {
                crate::syntax::ast::Declaration::Behavior(_) => {},
                _ => panic!("Expected Behavior declaration"),
            }
        }
    }

    // ===== Comprehensive edge case tests =====

    #[test]
    fn test_life_arc_with_no_transitions(name in valid_ident(), state_name in valid_ident()) {
        let input = format!("life_arc {} {{\n    state {} {{}}\n}}", name, state_name);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse life arc with no transitions: {:?}", result.err());
    }

    #[test]
    fn test_life_arc_with_multiple_transitions(
        name in valid_ident(),
        state_name in valid_ident(),
        targets in prop::collection::vec(valid_ident(), 2..5)
    ) {
        let transitions = targets.iter()
            .map(|target| format!("        on ready -> {}", target))
            .collect::<Vec<_>>()
            .join("\n");
        let input = format!("life_arc {} {{\n    state {} {{\n{}\n    }}\n}}", name, state_name, transitions);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse life arc with multiple transitions: {:?}", result.err());
    }

    #[test]
    fn test_behavior_tree_deeply_nested(name in valid_ident()) {
        let input = format!(
            "behavior {} {{\n    then {{\n        choose {{\n            then {{\n                action\n            }}\n        }}\n    }}\n}}",
            name
        );
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse deeply nested behavior tree: {:?}", result.err());
    }

    #[test]
    fn test_behavior_tree_with_action_params(
        name in valid_ident(),
        action in valid_ident(),
        params in prop::collection::vec(valid_field(), 1..4)
    ) {
        let params_str = params.iter()
            .map(|(k, v)| format!("{}: {}", k, v))
            .collect::<Vec<_>>()
            .join(", ");
        let input = format!("behavior {} {{\n    {}({})\n}}", name, action, params_str);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse behavior with action params: {:?}", result.err());
    }

    #[test]
    fn test_behavior_tree_with_subtree_reference(
        name in valid_ident(),
        subtree_path in prop::collection::vec(valid_ident(), 1..3)
    ) {
        let path = subtree_path.join("::");
        let input = format!("behavior {} {{\n    include {}\n}}", name, path);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse behavior with subtree: {:?}", result.err());
    }

    #[test]
    fn test_behavior_selector_with_many_children(
        name in valid_ident(),
        children in prop::collection::vec(valid_ident(), 2..10)
    ) {
        let children_str = children.iter()
            .map(|c| format!("        {}", c))
            .collect::<Vec<_>>()
            .join("\n");
        let input = format!("behavior {} {{\n    choose {{\n{}\n    }}\n}}", name, children_str);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse selector with many children: {:?}", result.err());
    }

    #[test]
    fn test_behavior_sequence_with_many_children(
        name in valid_ident(),
        children in prop::collection::vec(valid_ident(), 2..10)
    ) {
        let children_str = children.iter()
            .map(|c| format!("        {}", c))
            .collect::<Vec<_>>()
            .join("\n");
        let input = format!("behavior {} {{\n    then {{\n{}\n    }}\n}}", name, children_str);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse sequence with many children: {:?}", result.err());
    }

    #[test]
    fn test_life_arc_transition_with_literal_condition(
        name in valid_ident(),
        state_name in valid_ident(),
        target in valid_ident(),
        val in valid_int()
    ) {
        let input = format!("life_arc {} {{\n    state {} {{\n        on {} -> {}\n    }}\n}}", name, state_name, val, target);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse life arc with literal condition: {:?}", result.err());
    }

    #[test]
    fn test_life_arc_transition_with_bool_condition(
        name in valid_ident(),
        state_name in valid_ident(),
        target in valid_ident(),
        val in prop::sample::select(vec![true, false])
    ) {
        let input = format!("life_arc {} {{\n    state {} {{\n        on {} -> {}\n    }}\n}}", name, state_name, val, target);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse life arc with bool condition: {:?}", result.err());
    }

    // ===== Comparison expression tests =====

    #[test]
    fn test_comparison_all_operators(
        ident in valid_ident(),
        val in valid_int()
    ) {
        for op in &[">", ">=", "<", "<="] {
            let comp = format!("{} {} {}", ident, op, val);
            let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
            let lexer = Lexer::new(&input);
            let parser = FileParser::new();
            let result = parser.parse(lexer);
            assert!(result.is_ok(), "Failed to parse comparison '{}': {:?}", comp, result.err());
        }
    }

    #[test]
    fn test_comparison_with_int(comp in valid_comparison_expr()) {
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse comparison '{}': {:?}", comp, result.err());
    }

    #[test]
    fn test_comparison_gt(ident in valid_ident(), val in valid_int()) {
        let comp = format!("{} > {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse > comparison: {:?}", result.err());
    }

    #[test]
    fn test_comparison_gte(ident in valid_ident(), val in valid_int()) {
        let comp = format!("{} >= {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse >= comparison: {:?}", result.err());
    }

    #[test]
    fn test_comparison_lt(ident in valid_ident(), val in valid_int()) {
        let comp = format!("{} < {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse < comparison: {:?}", result.err());
    }

    #[test]
    fn test_comparison_lte(ident in valid_ident(), val in valid_int()) {
        let comp = format!("{} <= {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse <= comparison: {:?}", result.err());
    }

    #[test]
    fn test_comparison_with_float(
        ident in valid_ident(),
        val in valid_float()
    ) {
        let comp = format!("{} > {:.2}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse float comparison: {:?}", result.err());
    }

    #[test]
    fn test_comparison_with_negative_int(
        ident in valid_ident(),
        val in -100i64..0i64
    ) {
        let comp = format!("{} < {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse comparison with negative: {:?}", result.err());
    }

    #[test]
    fn test_multiple_transitions_with_comparisons(
        name in valid_ident(),
        state_name in valid_ident(),
        comparisons in prop::collection::vec(
            (valid_ident(), prop::sample::select(vec![">", "<", ">=", "<="]), valid_int(), valid_ident()),
            2..5
        )
    ) {
        let transitions = comparisons.iter()
            .map(|(var, op, val, target)| format!("        on {} {} {} -> {}", var, op, val, target))
            .collect::<Vec<_>>()
            .join("\n");
        let input = format!("life_arc {} {{\n    state {} {{\n{}\n    }}\n}}", name, state_name, transitions);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse multiple comparison transitions: {:?}", result.err());
    }

    // ===== Equality expression tests =====

    #[test]
    fn test_equality_with_string(
        ident in valid_ident(),
        val in valid_string()
    ) {
        let comp = format!("{} is \"{}\"", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse equality with string: {:?}", result.err());
    }

    #[test]
    fn test_equality_with_int(
        ident in valid_ident(),
        val in valid_int()
    ) {
        let comp = format!("{} is {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse equality with int: {:?}", result.err());
    }

    #[test]
    fn test_equality_with_float(
        ident in valid_ident(),
        val in valid_float()
    ) {
        let comp = format!("{} is {:.2}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse equality with float: {:?}", result.err());
    }

    #[test]
    fn test_equality_with_bool(
        ident in valid_ident(),
        val in prop::sample::select(vec![true, false])
    ) {
        let comp = format!("{} is {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", comp);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse equality with bool: {:?}", result.err());
    }

    #[test]
    fn test_equality_multiple_transitions(
        name in valid_ident(),
        state_name in valid_ident(),
        equalities in prop::collection::vec(
            (valid_ident(), prop_oneof![
                valid_int().prop_map(|n| n.to_string()),
                valid_string().prop_map(|s| format!("\"{}\"", s)),
                Just("true".to_string()),
                Just("false".to_string()),
            ], valid_ident()),
            2..5
        )
    ) {
        let transitions = equalities.iter()
            .map(|(var, val, target)| format!("        on {} is {} -> {}", var, val, target))
            .collect::<Vec<_>>()
            .join("\n");
        let input = format!("life_arc {} {{\n    state {} {{\n{}\n    }}\n}}", name, state_name, transitions);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse multiple equality transitions: {:?}", result.err());
    }

    #[test]
    fn test_equality_mixed_with_comparisons(
        name in valid_ident(),
        state_name in valid_ident()
    ) {
        let input = format!(
            "life_arc {} {{\n    state {} {{\n        on age > 12 -> teen\n        on status is active -> active_state\n        on energy < 0.3 -> tired\n        on completed is true -> done\n    }}\n}}",
            name, state_name
        );
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse mixed equality and comparisons: {:?}", result.err());
    }

    // ===== Logical operator tests =====

    #[test]
    fn test_logical_and(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        val1 in valid_int(),
        val2 in valid_int()
    ) {
        let cond = format!("{} > {} and {} < {}", ident1, val1, ident2, val2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'and' operator: {:?}", result.err());
    }

    #[test]
    fn test_logical_or(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        val1 in valid_int(),
        val2 in valid_int()
    ) {
        let cond = format!("{} > {} or {} < {}", ident1, val1, ident2, val2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'or' operator: {:?}", result.err());
    }

    #[test]
    fn test_logical_not_with_identifier(ident in valid_ident()) {
        let cond = format!("not {}", ident);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'not' operator with identifier: {:?}", result.err());
    }

    #[test]
    fn test_logical_not_with_comparison(
        ident in valid_ident(),
        val in valid_int()
    ) {
        let cond = format!("not {} > {}", ident, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'not' with comparison: {:?}", result.err());
    }

    #[test]
    fn test_and_with_equality(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        val in valid_string()
    ) {
        let cond = format!("{} is true and {} is \"{}\"", ident1, ident2, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'and' with equality: {:?}", result.err());
    }

    #[test]
    fn test_or_with_equality(
        ident1 in valid_ident(),
        ident2 in valid_ident()
    ) {
        let cond = format!("{} is false or {} is true", ident1, ident2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'or' with equality: {:?}", result.err());
    }

    #[test]
    fn test_chained_and(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        ident3 in valid_ident(),
        val1 in valid_int(),
        val2 in valid_int(),
        val3 in valid_int()
    ) {
        let cond = format!("{} > {} and {} < {} and {} is {}", ident1, val1, ident2, val2, ident3, val3);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse chained 'and': {:?}", result.err());
    }

    #[test]
    fn test_chained_or(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        ident3 in valid_ident()
    ) {
        let cond = format!("{} or {} or {}", ident1, ident2, ident3);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse chained 'or': {:?}", result.err());
    }

    #[test]
    fn test_mixed_and_or(
        ident1 in valid_ident(),
        ident2 in valid_ident(),
        ident3 in valid_ident(),
        val1 in valid_int(),
        val2 in valid_int()
    ) {
        // Tests precedence: 'and' binds tighter than 'or'
        // This should parse as: (ident1 > val1 and ident2 < val2) or ident3
        let cond = format!("{} > {} and {} < {} or {}", ident1, val1, ident2, val2, ident3);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse mixed 'and'/'or': {:?}", result.err());
    }

    #[test]
    fn test_not_not(ident in valid_ident()) {
        let cond = format!("not not {}", ident);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse double 'not': {:?}", result.err());
    }

    #[test]
    fn test_not_with_and(
        ident1 in valid_ident(),
        ident2 in valid_ident()
    ) {
        // Tests that 'not' binds tighter than 'and'
        // This should parse as: (not ident1) and ident2
        let cond = format!("not {} and {}", ident1, ident2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse 'not' with 'and': {:?}", result.err());
    }

    #[test]
    fn test_complex_nested_logic(
        name in valid_ident(),
        state_name in valid_ident()
    ) {
        let input = format!(
            "life_arc {} {{\n    state {} {{\n        on age > 18 and status is active and energy > 0.5 -> state1\n        on tired or hungry or sick -> state2\n        on not ready and not completed -> state3\n        on health > 50 and not sick or emergency -> state4\n    }}\n}}",
            name, state_name
        );
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse complex nested logic: {:?}", result.err());
    }

    // ===== Field access tests =====

    #[test]
    fn test_field_access_self(field in valid_ident(), val in valid_int()) {
        let cond = format!("self.{} > {}", field, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse self field access: {:?}", result.err());
    }

    #[test]
    fn test_field_access_other(field in valid_ident(), val in valid_int()) {
        let cond = format!("other.{} < {}", field, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse other field access: {:?}", result.err());
    }

    #[test]
    fn test_field_access_with_equality(
        field in valid_ident(),
        val in valid_string()
    ) {
        let cond = format!("self.{} is \"{}\"", field, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access with equality: {:?}", result.err());
    }

    #[test]
    fn test_field_access_with_bool(field in valid_ident()) {
        let cond = format!("self.{} is true", field);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access with bool: {:?}", result.err());
    }

    #[test]
    fn test_nested_field_access(
        field1 in valid_ident(),
        field2 in valid_ident(),
        val in valid_int()
    ) {
        let cond = format!("self.{}.{} > {}", field1, field2, val);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse nested field access: {:?}", result.err());
    }

    #[test]
    fn test_field_access_with_and(
        field1 in valid_ident(),
        field2 in valid_ident(),
        val1 in valid_int(),
        val2 in valid_int()
    ) {
        let cond = format!("self.{} > {} and other.{} < {}", field1, val1, field2, val2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access with 'and': {:?}", result.err());
    }

    #[test]
    fn test_field_access_with_or(
        field1 in valid_ident(),
        field2 in valid_ident()
    ) {
        let cond = format!("self.{} or other.{}", field1, field2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access with 'or': {:?}", result.err());
    }

    #[test]
    fn test_field_access_with_not(field in valid_ident()) {
        let cond = format!("not self.{}", field);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access with 'not': {:?}", result.err());
    }

    #[test]
    fn test_field_access_both_sides(
        field1 in valid_ident(),
        field2 in valid_ident()
    ) {
        let cond = format!("self.{} > other.{}", field1, field2);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access on both sides: {:?}", result.err());
    }

    #[test]
    fn test_field_access_vs_identifier(
        field in valid_ident(),
        ident in valid_ident()
    ) {
        let cond = format!("self.{} > {}", field, ident);
        let input = format!("life_arc Test {{\n    state s {{\n        on {} -> next\n    }}\n}}", cond);
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse field access vs identifier: {:?}", result.err());
    }

    #[test]
    fn test_complex_field_access(
        name in valid_ident(),
        state_name in valid_ident()
    ) {
        let input = format!(
            "life_arc {} {{\n    state {} {{\n        on self.age > 18 and self.status is active -> state1\n        on other.bond < 0.3 or self.energy < 0.2 -> state2\n        on not self.ready and other.level > 5 -> state3\n        on self.health > other.health -> state4\n    }}\n}}",
            name, state_name
        );
        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok(), "Failed to parse complex field access: {:?}", result.err());
    }
}

// ===== Prose block property tests =====

fn valid_prose_content() -> impl Strategy<Value = String> {
    // Prose content without --- at line start
    prop::string::string_regex("[^\n]*(\n[^-][^\n]*)*").unwrap()
}

proptest! {
    #[test]
    fn test_prose_block_roundtrip(
        tag in valid_ident(),
        content in valid_prose_content()
    ) {
        let input = format!("---{}\n{}\n---", tag, content);
        let lexer = Lexer::new(&input);
        let tokens: Vec<Token> = lexer.map(|(_, tok, _)| tok).collect();

        assert_eq!(tokens.len(), 1);
        match &tokens[0] {
            Token::ProseBlock(pb) => {
                assert_eq!(pb.tag, tag);
                assert_eq!(pb.content.trim(), content.trim());
            }
            _ => panic!("Expected ProseBlock token"),
        }
    }

    #[test]
    fn test_character_with_prose(
        name in valid_ident(),
        tag in valid_ident(),
        content in valid_prose_content()
    ) {
        let input = format!(
            "character {} {{\n    {}: ---{}\n{}\n---\n}}",
            name, tag, tag, content
        );

        let lexer = Lexer::new(&input);
        let parser = FileParser::new();
        let result = parser.parse(lexer);

        assert!(result.is_ok(), "Failed to parse character with prose:\n{}\nError: {:?}", input, result.err());
    }
}

// ===== Edge case tests =====

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

    #[test]
    fn test_empty_input_parses() {
        let lexer = Lexer::new("");
        let parser = FileParser::new();
        let result = parser.parse(lexer);
        assert!(result.is_ok());
        assert_eq!(result.unwrap().declarations.len(), 0);
    }

    proptest! {

        #[test]
        fn test_only_whitespace_parses(ws in "[ \t\n]{1,100}") {
            let lexer = Lexer::new(&ws);
            let parser = FileParser::new();
            let result = parser.parse(lexer);
            assert!(result.is_ok());
            assert_eq!(result.unwrap().declarations.len(), 0);
        }

        #[test]
        fn test_only_comments_parses(
            n in 1usize..10,
            comment_content in valid_string()
        ) {
            let input = (0..n)
                .map(|_| format!("// {}", comment_content))
                .collect::<Vec<_>>()
                .join("\n");

            let lexer = Lexer::new(&input);
            let parser = FileParser::new();
            let result = parser.parse(lexer);
            assert!(result.is_ok());
            assert_eq!(result.unwrap().declarations.len(), 0);
        }

        #[test]
        fn test_unicode_in_strings(s in "[^\"\\\\ ]{1,20}") {
            let input = format!("character Test {{ name: \"{}\" }}", s);
            let lexer = Lexer::new(&input);
            let parser = FileParser::new();
            let result = parser.parse(lexer);
            // Should either parse or fail gracefully
            let _ = result;
        }

        #[test]
        fn test_nested_objects(depth in 1usize..4) {
            let mut input = String::from("character Test { data: ");
            for _ in 0..depth {
                input.push_str("{ inner: ");
            }
            input.push_str("42");
            for _ in 0..depth {
                input.push_str(" }");
            }
            input.push_str(" }");

            let lexer = Lexer::new(&input);
            let parser = FileParser::new();
            let result = parser.parse(lexer);
            assert!(result.is_ok(), "Failed to parse nested objects (depth {}): {}", depth, input);
        }
    }
}
