# pyright: reportRedeclaration=false
"""Step definitions for actor remove impact computation feature."""

from __future__ import annotations

from typing import Any
from unittest.mock import MagicMock, patch

from behave import given, then, when
from typer.testing import CliRunner  # noqa: F401 - used via context.runner

from cleveragents.cli.commands.actor import app as actor_app
from cleveragents.domain.models.core.actor import Actor


def _make_actor(
    *,
    name: str = "local/test-actor",
    provider: str = "test-provider",
    model: str = "test-model",
) -> Actor:
    return Actor(
        id=1,
        name=name,
        provider=provider,
        model=model,
        config_blob={},
        config_hash="abcdef12",
        graph_descriptor=None,
        unsafe=False,
        is_default=False,
        is_built_in=False,
    )


@given(
    'an actor "{actor_name}" referenced by {sessions:d} sessions, '
    "{plans:d} active plan, and {actions:d} actions"
)
def step_actor_with_references(
    context: Any, actor_name: str, sessions: int, plans: int, actions: int
) -> None:
    """Set up context with an actor that has known reference counts."""
    context.actor_name = actor_name
    context.expected_sessions = sessions
    context.expected_plans = plans
    context.expected_actions = actions


@given('an actor "{actor_name}" with no references')
def step_actor_no_references(context: Any, actor_name: str) -> None:
    """Set up context with an actor that has no references."""
    context.actor_name = actor_name
    context.expected_sessions = 0
    context.expected_plans = 0
    context.expected_actions = 0


@when('I run actor remove for "{actor_name}"')
def step_run_actor_remove(context: Any, actor_name: str) -> None:
    """Invoke the actor remove command with mocked services and impact counts."""
    sessions = getattr(context, "expected_sessions", 0)
    plans = getattr(context, "expected_plans", 0)
    actions = getattr(context, "expected_actions", 0)

    mock_actor = _make_actor(name=actor_name)

    with (
        patch("cleveragents.cli.commands.actor._get_services") as mock_get_services,
        patch("cleveragents.cli.commands.actor._compute_actor_impact") as mock_impact,
    ):
        mock_registry = MagicMock()
        mock_registry.get_actor.return_value = mock_actor
        mock_get_services.return_value = (MagicMock(), mock_registry)
        mock_impact.return_value = (sessions, plans, actions)

        context.result = context.runner.invoke(actor_app, ["remove", actor_name])
        context.mock_impact = mock_impact
        context.mock_registry = mock_registry


@then('the Impact panel should show "{text}" for Sessions')
def step_impact_sessions(context: Any, text: str) -> None:
    """Assert the Sessions line in the Impact panel shows the expected text."""
    output = context.result.output
    assert text in output, (
        f"Expected '{text}' in output for Sessions, but got:\n{output}"
    )


@then('the Impact panel should show "{text}" for Active Plans')
def step_impact_plans(context: Any, text: str) -> None:
    """Assert the Active Plans line in the Impact panel shows the expected text."""
    output = context.result.output
    assert text in output, (
        f"Expected '{text}' in output for Active Plans, but got:\n{output}"
    )


@then('the Impact panel should show "{text}" for Actions Referencing')
def step_impact_actions(context: Any, text: str) -> None:
    """Assert the Actions Referencing line in the Impact panel shows the expected text."""
    output = context.result.output
    assert text in output, (
        f"Expected '{text}' in output for Actions Referencing, but got:\n{output}"
    )
