"""
AgentFinishedCritic implementation.

This critic evaluates whether an agent properly finished a task by checking:
1. The agent's last action was a FinishAction (proper completion)
2. The generated git patch is non-empty (actual changes were made)
"""

from collections.abc import Sequence
from typing import TYPE_CHECKING

from openhands.sdk.critic.base import CriticBase, CriticResult
from openhands.sdk.logger import get_logger
from openhands.sdk.tool.builtins.finish import FinishAction


if TYPE_CHECKING:
    from openhands.sdk.event.base import LLMConvertibleEvent


logger = get_logger(__name__)


class AgentFinishedCritic(CriticBase):
    """
    Critic that evaluates whether an agent properly finished a task.

    This critic checks two main criteria:
    1. The agent's last action was a FinishAction (proper completion)
    2. The generated git patch is non-empty (actual changes were made)
    """

    def evaluate(
        self, events: Sequence["LLMConvertibleEvent"], git_patch: str | None = None
    ) -> CriticResult:
        """
        Evaluate if an agent properly finished with a non-empty git patch.

        Args:
            events: List of events from the agent's execution
            git_patch: Optional git patch generated by the agent

        Returns:
            CriticResult with score 1.0 if successful, 0.0 otherwise
        """
        reasons = []

        # Check if git patch is non-empty
        if not git_patch or not git_patch.strip():
            reasons.append("Empty git patch")
            logger.debug("AgentFinishedCritic: Empty git patch")
            return CriticResult(
                score=0.0,
                message="Agent did not produce a non-empty git patch. "
                + "; ".join(reasons),
            )

        # Check if agent properly finished with FinishAction
        if not self._has_finish_action(events):
            reasons.append("No FinishAction found")
            logger.debug("AgentFinishedCritic: No FinishAction")
            return CriticResult(
                score=0.0,
                message="Agent did not finish properly. " + "; ".join(reasons),
            )

        logger.debug("AgentFinishedCritic: Successfully completed")
        return CriticResult(
            score=1.0,
            message="Agent completed with FinishAction and non-empty patch",
        )

    def _has_finish_action(self, events: Sequence["LLMConvertibleEvent"]) -> bool:
        """Check if the last action was a FinishAction."""
        if not events:
            return False

        # Look for the last ActionEvent in the history
        from openhands.sdk.event.llm_convertible.action import ActionEvent

        for event in reversed(events):
            if isinstance(event, ActionEvent):
                if event.action and isinstance(event.action, FinishAction):
                    return True
                return False

        return False
