"""Steps for executing session CLI commands to cover MCP logger lines."""

import logging
from typing import Any
from unittest.mock import Mock, patch

from behave import given, then, when

from cleveragents.cli.commands.session import create as session_create
from cleveragents.cli.commands.session import list_sessions


@given("a clean test database for session cli execution tests")
def step_clean_database(context: Any) -> None:
    """Initialize a clean test database."""
    context.db_initialized = True
    context.mcp_logger = logging.getLogger("cleveragents.mcp")
    context.original_level = context.mcp_logger.level
    context.logger_level_changes = []


@given("a mock A2A facade for session cli execution tests")
def step_mock_a2a_facade(context: Any) -> None:
    """Mock the A2A facade."""
    context.a2a_facade_mock = Mock()


@given("the database is initialized for session cli execution tests")
def step_db_initialized(context: Any) -> None:
    """Ensure database is initialized."""
    context.db_initialized = True
    context.mcp_logger = logging.getLogger("cleveragents.mcp")
    context.original_level = context.mcp_logger.level
    context.logger_level_changes = []


@given("the session service raises an exception on create")
def step_service_raises_on_create(context: Any) -> None:
    """Configure session service to raise exception."""
    from cleveragents.core.exceptions import CleverAgentsError

    context.service_exception_on_create = CleverAgentsError("Test create error")


@given("the session service raises an exception on list")
def step_service_raises_on_list(context: Any) -> None:
    """Configure session service to raise exception."""
    from cleveragents.core.exceptions import CleverAgentsError

    context.service_exception_on_list = CleverAgentsError("Test list error")


@when("I execute session create with format {fmt}")
def step_execute_session_create(context: Any, fmt: str) -> None:
    """Execute session create command with specified format."""
    # Track logger level changes
    original_setLevel = context.mcp_logger.setLevel

    def track_setLevel(level: int) -> None:
        context.logger_level_changes.append(level)
        return original_setLevel(level)

    with (
        patch.object(context.mcp_logger, "setLevel", side_effect=track_setLevel),
        patch(
            "cleveragents.cli.commands.session._get_session_service"
        ) as mock_get_service,
    ):
        mock_service = Mock()
        if hasattr(context, "service_exception_on_create"):
            mock_service.create.side_effect = context.service_exception_on_create
        else:
            mock_service.create.return_value = Mock()
        mock_get_service.return_value = mock_service

        try:
            with patch("cleveragents.cli.commands.session.typer.echo"):
                session_create(actor=None, fmt=fmt)
            context.create_success = True
        except SystemExit:
            context.create_success = True
        except Exception as e:
            context.create_error = e


@when("I execute session list with format {fmt}")
def step_execute_session_list(context: Any, fmt: str) -> None:
    """Execute session list command with specified format."""
    # Track logger level changes
    original_setLevel = context.mcp_logger.setLevel

    def track_setLevel(level: int) -> None:
        context.logger_level_changes.append(level)
        return original_setLevel(level)

    with (
        patch.object(context.mcp_logger, "setLevel", side_effect=track_setLevel),
        patch(
            "cleveragents.cli.commands.session._get_session_service"
        ) as mock_get_service,
    ):
        mock_service = Mock()
        if hasattr(context, "service_exception_on_list"):
            mock_service.list.side_effect = context.service_exception_on_list
        else:
            mock_service.list.return_value = []
        mock_get_service.return_value = mock_service

        try:
            with patch("cleveragents.cli.commands.session.typer.echo"):
                list_sessions(fmt=fmt)
            context.list_success = True
        except SystemExit:
            context.list_success = True
        except Exception as e:
            context.list_error = e


@then("the MCP logger should be set to CRITICAL during execution")
def step_logger_set_to_critical(context: Any) -> None:
    """Verify MCP logger was set to CRITICAL."""
    assert logging.CRITICAL in context.logger_level_changes, (
        f"MCP logger should have been set to CRITICAL. Changes: {context.logger_level_changes}"
    )


@then("the MCP logger should be restored after execution")
def step_logger_restored(context: Any) -> None:
    """Verify MCP logger was restored to original level."""
    # After execution, the logger should be back to original level
    current_level = context.mcp_logger.level
    # The finally block should have restored it
    assert current_level == context.original_level


@then("the MCP logger should NOT be set to CRITICAL")
def step_logger_not_critical(context: Any) -> None:
    """Verify MCP logger was NOT set to CRITICAL."""
    assert logging.CRITICAL not in context.logger_level_changes, (
        f"MCP logger should NOT have been set to CRITICAL. Changes: {context.logger_level_changes}"
    )


@then("the MCP logger should be restored in the finally block")
def step_logger_restored_in_finally(context: Any) -> None:
    """Verify MCP logger restoration in finally block."""
    # Even with exception, the finally block should restore the level
    current_level = context.mcp_logger.level
    assert current_level == context.original_level, (
        f"Logger level {current_level} should match original {context.original_level}"
    )
    assert hasattr(context, "service_exception_on_create") or hasattr(
        context, "service_exception_on_list"
    ), "Expected exception configuration"
