"""Runtime instructions history processor.

This module provides a history processor that injects runtime context
instructions (elapsed time, token usage, system reminders) into the
message history before each model request.

The runtime instructions are appended to the last ModelRequest's parts
as a UserPromptPart, providing the model with up-to-date context about
the current session state.

Note:
    This processor should be used with AgentContext that has model_cfg set
    for handoff threshold warnings to be displayed.

Example::

    from contextlib import AsyncExitStack
    from pydantic_ai import Agent

    from ya_agent_sdk.context import AgentContext, ModelConfig
    from ya_agent_sdk.environment.local import LocalEnvironment
    from ya_agent_sdk.filters.runtime_instructions import inject_runtime_instructions

    async with AsyncExitStack() as stack:
        env = await stack.enter_async_context(LocalEnvironment())
        ctx = await stack.enter_async_context(
            AgentContext(
                env=env,
                model_cfg=ModelConfig(
                    context_window=200000,
                    proactive_context_management_threshold=0.5,
                ),
            )
        )
        agent = Agent(
            'openai:gpt-4',
            deps_type=AgentContext,
            history_processors=[inject_runtime_instructions],
            metadata=lambda _: {'context_manage_tool': 'handoff'},
        )
        result = await agent.run('Your prompt here', deps=ctx)
"""

from pydantic_ai.messages import ModelMessage, ModelRequest, RetryPromptPart, ToolReturnPart, UserPromptPart
from pydantic_ai.tools import RunContext

from ya_agent_sdk.context import AgentContext


async def inject_runtime_instructions(
    ctx: RunContext[AgentContext],
    message_history: list[ModelMessage],
) -> list[ModelMessage]:
    """Inject runtime instructions into the last ModelRequest.

    This is a pydantic-ai history_processor that appends runtime context
    instructions (elapsed time, token usage, handoff warnings) to the last
    ModelRequest in the message history.

    The instructions are generated by AgentContext.get_context_instructions()
    and include:
    - Elapsed time since session start
    - Model configuration (context window size)
    - Token usage from the current request
    - System reminders (e.g., handoff threshold warning)

    Args:
        ctx: Runtime context containing AgentContext with model configuration.
        message_history: Current message history to process.

    Returns:
        Processed message history with runtime instructions injected into
        the last ModelRequest, or unchanged history if no ModelRequest found.

    Example:
        agent = Agent(
            'openai:gpt-4',
            deps_type=AgentContext,
            history_processors=[inject_runtime_instructions],
        )
    """
    # Find the last ModelRequest in message history
    last_request: ModelRequest | None = None
    for msg in reversed(message_history):
        if isinstance(msg, ModelRequest):
            last_request = msg
            break

    if not last_request:
        return message_history

    # Determine if this is a user prompt (not a tool response or retry)
    # We include subagent info only on user prompts to reduce noise
    # Exception: force_inject_instructions overrides this after context reset (handoff/compact)
    is_user_prompt = not any(isinstance(part, (ToolReturnPart, RetryPromptPart)) for part in last_request.parts)
    if ctx.deps.force_inject_instructions:
        is_user_prompt = True

    # Get runtime instructions from AgentContext
    instructions = await ctx.deps.get_context_instructions(ctx, is_user_prompt=is_user_prompt)

    if not instructions:
        return message_history

    # Append runtime instructions as a UserPromptPart
    runtime_part = UserPromptPart(content=instructions)
    last_request.parts = [*last_request.parts, runtime_part]

    return message_history
