"""Response processing helpers for AgentRunner.

Extracted from agent.py to reduce file size.
Spec source: vectl step ``shrink-agent-py`` in ``gate-review-debt`` phase.
"""

# @invar:allow shell_result: Response helpers return Result types
# @shell_orchestration: Response helpers extracted from AgentRunner for state transitions

from __future__ import annotations

from typing import Any

from returns.result import Result, Success

from anima.core.lifecycle import LifecycleEvent
from anima.core.schemas import (
    AgentResult,
    AgentState,
    AnimaError,
    CompletionPolicy,
    TokenUsage,
)
from anima.shell.state import transition_state


# @invar:allow shell_result: Internal helper preserving original AgentRunner method signature
# @shell_orchestration: Imports pydantic_ai.messages for response extraction
# @shell_complexity: Message list traversal with type checking
def extract_last_response_text(messages: list[Any]) -> str | None:
    """Extract text content from the last model response in message history.

    Args:
        messages: PydanticAI message history.

    Returns:
        Text content of the last model response, or None.
    """
    from pydantic_ai.messages import ModelResponse

    for msg in reversed(messages):
        if isinstance(msg, ModelResponse):
            for part in msg.parts:
                if hasattr(part, "part_kind") and part.part_kind == "text":
                    return part.content
    return None


# @invar:allow shell_result: Internal helper returning int streak count
# @shell_orchestration: Extracted from AgentRunner, retained in shell for completion_policy access
def record_tool_usage(
    result: Any,
    no_tool_streak: int,
    completion_policy: CompletionPolicy,
) -> int:
    """Record tool usage state for auto completion.

    Spec source: medium-fixes.reduce-agent-size target (e).

    Args:
        result: The node result from PydanticAI iteration.
        no_tool_streak: Current consecutive turns without tool calls.
        completion_policy: The agent's completion policy.

    Returns:
        Updated no_tool_streak value.
    """
    tool_calls_in_response = bool(getattr(result, "tool_call_results", None))
    if tool_calls_in_response:
        return 0
    if completion_policy == CompletionPolicy.auto:
        return no_tool_streak + 1
    return no_tool_streak


def check_auto_complete(
    completion_policy: CompletionPolicy,
    no_tool_streak: int,
    instance_id: str,
    token_usage: TokenUsage,
) -> Result[AgentResult, AnimaError] | None:
    """Check for auto-completion. Returns completed result if triggered.

    Args:
        completion_policy: The agent's completion policy.
        no_tool_streak: Consecutive turns without tool calls.
        instance_id: The agent's unique identifier.
        token_usage: Current token usage for result construction.

    Returns:
        Success with completed AgentResult if auto-complete triggered, else None.
    """
    if completion_policy == CompletionPolicy.auto and no_tool_streak >= 2:
        transition_state(
            instance_id,
            LifecycleEvent.auto_complete,
            result_ref=None,
        )
        return Success(
            AgentResult(
                final_state=AgentState.completed,
                token_usage=token_usage,
            )
        )
    return None


__all__ = [
    "check_auto_complete",
    "extract_last_response_text",
    "record_tool_usage",
]
