"""Step definitions for tui_thought_block.feature."""

from __future__ import annotations

from behave import then, when

from cleveragents.domain.models.thought.thought_block import ThoughtBlock
from cleveragents.tui.widgets.thought_block import ThoughtBlockWidget

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _make_lines(n: int) -> str:
    """Return a string with *n* numbered lines."""
    return "\n".join(f"Line {i + 1}" for i in range(n))


# ---------------------------------------------------------------------------
# ThoughtBlock domain model steps
# ---------------------------------------------------------------------------


@when('I create a thought block with content "{content}"')
def step_create_thought_block(context, content):
    context.thought = ThoughtBlock(content=content)


@when('I create a thought block with content "{content}" and max_lines {n:d}')
def step_create_thought_block_custom_max(context, content, n):
    context.thought = ThoughtBlock(content=content, max_lines=n)


@when("I create a thought block with {n:d} lines of content")
def step_create_thought_block_n_lines(context, n):
    context.thought = ThoughtBlock(content=_make_lines(n))


@when("I create a thought block with exactly {n:d} lines of content")
def step_create_thought_block_exactly_n_lines(context, n):
    context.thought = ThoughtBlock(content=_make_lines(n))


@when("I create a thought block with empty content")
def step_create_thought_block_empty(context):
    context.thought = ThoughtBlock(content="")


@when("I expand the thought block")
def step_expand_thought_block(context):
    context.thought.expand()


@when("I collapse the thought block")
def step_collapse_thought_block(context):
    context.thought.collapse()


@when("I toggle the thought block")
def step_toggle_thought_block(context):
    context.thought.toggle()


@then('the thought block content should be "{expected}"')
def step_thought_block_content(context, expected):
    assert context.thought.content == expected, (
        f"Expected content {expected!r}, got {context.thought.content!r}"
    )


@then("the thought block max_lines should be {n:d}")
def step_thought_block_max_lines(context, n):
    assert context.thought.max_lines == n, (
        f"Expected max_lines {n}, got {context.thought.max_lines}"
    )


@then("the thought block should be collapsed by default")
def step_thought_block_collapsed_default(context):
    assert context.thought.expanded is False, "Expected thought block to be collapsed"


@then("the thought block should be collapsed")
def step_thought_block_collapsed(context):
    assert context.thought.expanded is False, "Expected thought block to be collapsed"


@then("the thought block should be expanded")
def step_thought_block_expanded(context):
    assert context.thought.expanded is True, "Expected thought block to be expanded"


@then("the thought block should not be truncated")
def step_thought_block_not_truncated(context):
    assert context.thought.is_truncated() is False, (
        "Expected thought block to not be truncated"
    )


@then("the thought block should be truncated")
def step_thought_block_truncated(context):
    assert context.thought.is_truncated() is True, (
        "Expected thought block to be truncated"
    )


@then("the thought block visible lines count should be {n:d}")
def step_thought_block_visible_lines_count(context, n):
    actual = len(context.thought.visible_lines())
    assert actual == n, f"Expected {n} visible lines, got {actual}"


@then("the thought block hidden line count should be {n:d}")
def step_thought_block_hidden_line_count(context, n):
    actual = context.thought.hidden_line_count()
    assert actual == n, f"Expected {n} hidden lines, got {actual}"


@then("the thought block lines count should be {n:d}")
def step_thought_block_lines_count(context, n):
    actual = len(context.thought.lines())
    assert actual == n, f"Expected {n} lines, got {actual}"


@then('the thought block rendered text should contain "{text}"')
def step_thought_block_rendered_text_contains(context, text):
    rendered = context.thought.rendered_text()
    assert text in rendered, f"Expected {text!r} in rendered text, got: {rendered!r}"


@then('the thought block rendered text should not contain "{text}"')
def step_thought_block_rendered_text_not_contains(context, text):
    rendered = context.thought.rendered_text()
    assert text not in rendered, (
        f"Expected {text!r} NOT in rendered text, got: {rendered!r}"
    )


@then("the thought block rendered text should be empty")
def step_thought_block_rendered_text_empty(context):
    rendered = context.thought.rendered_text()
    assert rendered == "", f"Expected empty rendered text, got: {rendered!r}"


# ---------------------------------------------------------------------------
# ThoughtBlockWidget steps
# ---------------------------------------------------------------------------


@when('I create a thought block widget with content "{content}"')
def step_create_widget(context, content):
    thought = ThoughtBlock(content=content)
    context.widget = ThoughtBlockWidget(thought=thought)


@when("I create a thought block widget with {n:d} lines of content")
def step_create_widget_n_lines(context, n):
    thought = ThoughtBlock(content=_make_lines(n))
    context.widget = ThoughtBlockWidget(thought=thought)


@when("I create a thought block widget with empty content")
def step_create_widget_empty(context):
    thought = ThoughtBlock(content="")
    context.widget = ThoughtBlockWidget(thought=thought)


@when("I toggle the thought block widget")
def step_toggle_widget(context):
    context.widget.toggle()


@when("I expand the thought block widget")
def step_expand_widget(context):
    context.widget.expand()


@when("I collapse the thought block widget")
def step_collapse_widget(context):
    context.widget.collapse()


@then('the widget thought content should be "{expected}"')
def step_widget_thought_content(context, expected):
    assert context.widget.thought.content == expected, (
        f"Expected widget thought content {expected!r}, "
        f"got {context.widget.thought.content!r}"
    )


@then("the widget should be collapsed")
def step_widget_collapsed(context):
    assert context.widget.is_expanded is False, "Expected widget to be collapsed"


@then("the widget should be expanded")
def step_widget_expanded(context):
    assert context.widget.is_expanded is True, "Expected widget to be expanded"


@then('the widget display text should contain "{text}"')
def step_widget_display_text_contains(context, text):
    assert text in context.widget._text, (
        f"Expected {text!r} in widget text, got: {context.widget._text!r}"
    )


@then('the widget CSS classes should contain "{cls}"')
def step_widget_css_class_contains(context, cls):
    assert cls in context.widget._classes, (
        f"Expected CSS class {cls!r} in {context.widget._classes}"
    )


@then('the widget CSS classes should not contain "{cls}"')
def step_widget_css_class_not_contains(context, cls):
    assert cls not in context.widget._classes, (
        f"Expected CSS class {cls!r} NOT in {context.widget._classes}"
    )
