"""Step definitions for tdd_plan_tree_correction_visual.feature.

Tests that corrected nodes (decisions with is_correction=True) are visually
marked in the plan tree output. This is a TDD scenario documenting the gap
where the current implementation does NOT visually distinguish corrected nodes.
"""

from __future__ import annotations

from behave import given, then, when
from behave.runner import Context
from ulid import ULID

from cleveragents.cli.commands.plan import build_decision_tree
from cleveragents.domain.models.core.decision import Decision, DecisionType

# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------

_PLAN_ID = str(ULID())


# ---------------------------------------------------------------------------
# Given steps
# ---------------------------------------------------------------------------


@given("a set of test decisions with a corrected decision")
def step_decisions_with_correction(context: Context) -> None:
    """Create a set of decisions where one is marked as a correction."""
    root_id = str(ULID())
    corrected_id = str(ULID())
    corrects_id = str(ULID())

    context.tdd_decisions = [
        # Root decision
        Decision(
            decision_id=root_id,
            plan_id=_PLAN_ID,
            sequence_number=0,
            decision_type=DecisionType.PROMPT_DEFINITION,
            question="What to build?",
            chosen_option="REST API",
        ),
        # Original decision that will be corrected
        Decision(
            decision_id=corrects_id,
            plan_id=_PLAN_ID,
            parent_decision_id=root_id,
            sequence_number=1,
            decision_type=DecisionType.STRATEGY_CHOICE,
            question="Which framework?",
            chosen_option="Django",
        ),
        # Corrected decision (is_correction=True)
        Decision(
            decision_id=corrected_id,
            plan_id=_PLAN_ID,
            parent_decision_id=root_id,
            sequence_number=2,
            decision_type=DecisionType.STRATEGY_CHOICE,
            question="Which framework?",
            chosen_option="FastAPI",
            is_correction=True,
            corrects_decision_id=corrects_id,
        ),
    ]
    context.tdd_corrected_id = corrected_id


# ---------------------------------------------------------------------------
# When steps
# ---------------------------------------------------------------------------


@when("I build the correction TDD test decision tree")
def step_build_tree_default(context: Context) -> None:
    """Build the decision tree from the test decisions."""
    context.tdd_tree_data = build_decision_tree(
        context.tdd_decisions,
        show_superseded=False,
        max_depth=0,
    )


# ---------------------------------------------------------------------------
# Then steps
# ---------------------------------------------------------------------------


@then("the tree should include a visual marker for the corrected decision")
def step_tree_has_correction_marker(context: Context) -> None:
    """Verify that the tree data includes a marker for the corrected decision."""
    tree_nodes: list[dict[str, object]] = context.tdd_tree_data

    # The tree_data is a list of root-level node dicts.
    # We need to search through it to find the corrected decision node
    # and verify it has a visual marker.

    def find_corrected_node(
        nodes: list[dict[str, object]],
    ) -> dict[str, object] | None:
        """Recursively search for the corrected decision node."""
        for node in nodes:
            if node.get("decision_id") == context.tdd_corrected_id:
                return node
            children = node.get("children", [])
            assert isinstance(children, list)
            result = find_corrected_node(children)
            if result is not None:
                return result
        return None

    corrected_node = find_corrected_node(tree_nodes)
    assert corrected_node is not None, (
        f"Corrected decision {context.tdd_corrected_id} not found in tree"
    )

    # Store the node for the next assertion
    context.tdd_corrected_node = corrected_node


@then(
    'the corrected decision label should contain "[corrected]" or "✎" or similar marker'
)
def step_corrected_label_has_marker(context: Context) -> None:
    """Verify that the corrected decision's label contains a visual marker.

    This assertion is expected to FAIL (via @tdd_expected_fail) because
    build_decision_tree does not currently include a 'label' key in its
    node dicts, and even if it did, it does not add visual markers for
    corrected decisions (is_correction=True). This TDD scenario documents
    the gap described in Spec Requirement #7.
    """
    corrected_node = context.tdd_corrected_node

    # The label should be in the node's label field.
    # build_decision_tree currently does NOT include a 'label' key in its
    # node dicts -- this assertion will fail with AssertionError, proving
    # the bug exists (Spec Requirement #7: corrected nodes must be visually
    # marked in the plan tree output).
    label = str(corrected_node.get("label", ""))

    # Check for common visual markers for corrections
    markers = ["[corrected]", "\u270e", "[correction]", "\u270f", "[fix]", "[amended]"]

    has_marker = any(marker in label for marker in markers)

    assert has_marker, (
        f"Corrected decision label '{label}' does not contain any visual marker. "
        f"Expected one of: {markers}. "
        f"build_decision_tree does not currently add visual markers for "
        f"decisions with is_correction=True (Spec Requirement #7 gap)."
    )
