"""Behave step definitions for dynamic_router coverage."""

from behave import given, then, when  # type: ignore
from behave.runner import Context  # type: ignore

from cleveragents.langgraph.dynamic_router import DynamicRouter
from cleveragents.langgraph.nodes import Edge


@given("a dynamic router with no rules")
def step_no_rules(context: Context):
    context.router = DynamicRouter()


@given('a dynamic router with a rule targeting "next" and no condition')
def step_rule_no_condition(context: Context):
    context.router = DynamicRouter(rules=[{"target": "next"}])


@given(
    'a dynamic router with a rule targeting "match_target" when message type is "match"'
)
def step_rule_with_condition_matches(context: Context):
    context.router = DynamicRouter(
        rules=[
            {
                "target": "match_target",
                "condition": lambda msg: msg.get("type") == "match",
            }
        ]
    )


@given(
    'a dynamic router with a rule targeting "conditional" when message type is "expected"'
)
def step_rule_with_condition_fails(context: Context):
    context.router = DynamicRouter(
        rules=[
            {
                "target": "conditional",
                "condition": lambda msg: msg.get("type") == "expected",
            }
        ]
    )


@when("I route the message")
def step_route_message(context: Context):
    # Parse message from scenario text (provided as JSON-like string)
    import json

    message_text = context.text.strip() if context.text else "{}"
    context.message = json.loads(message_text)
    context.result_edges = context.router.route(context.message)


@then("the router should return the default end edge")
def step_assert_default_edge(context: Context):
    assert context.result_edges == [Edge(source="start", target="end")]


@then('the router should return a single edge to "next"')
def step_assert_next_edge(context: Context):
    assert context.result_edges == [Edge(source="start", target="next")]


@then('the router should return a single edge to "match_target"')
def step_assert_match_edge(context: Context):
    assert context.result_edges == [Edge(source="start", target="match_target")]


@then("the router should return the default end edge even when rules do not match")
def step_assert_fallback_edge(context: Context):
    assert context.result_edges == [Edge(source="start", target="end")]
