from api.evals.base import EvalScenario, ScenarioTask
from api.evals.registry import register_scenario
from api.evals.execution import ScenarioExecutionTools
from api.models import EvalRunTask, PersistentAgentMessage


@register_scenario
class OverEagerFollowupScenario(EvalScenario, ScenarioExecutionTools):
    slug = "over_eager_followup"
    description = "Checks that an agent does not send multiple or pushy follow-ups after a clear 'stand by' message."
    tier = "core"
    category = "conversation"
    expected_runtime = "medium"
    cost_class = "medium"
    owner = "agent-platform"
    area = "agent_behavior"
    tags = ("conversation", "followup", "response_quality", "llm_judge")
    tasks = [
        ScenarioTask(name="inject_prompt", assertion_type="manual"),
        ScenarioTask(name="verify_outbound_count", assertion_type="manual"),
        ScenarioTask(name="verify_reply_neediness", assertion_type="llm_judge"),
    ]

    def run(self, run_id: str, agent_id: str) -> None:
        # Task 1: Inject prompt that should not require any follow-up
        self.record_task_result(run_id, None, EvalRunTask.Status.RUNNING, task_name="inject_prompt")

        prompt = "Thanks! I'll reach out later if needed. Please don't follow up unless I ask."
        with self.wait_for_agent_idle(agent_id, timeout=120):
            msg = self.inject_message(
                agent_id,
                prompt,
                trigger_processing=True,
                eval_run_id=run_id,
            )

        self.record_task_result(
            run_id,
            None,
            EvalRunTask.Status.PASSED,
            task_name="inject_prompt",
            observed_summary="Prompt injected and processing completed.",
            artifacts={"message": msg},
        )

        # Task 2: Verify number of outbound messages after the prompt
        self.record_task_result(run_id, None, EvalRunTask.Status.RUNNING, task_name="verify_outbound_count")

        outbound = list(
            PersistentAgentMessage.objects.filter(
                owner_agent_id=agent_id,
                is_outbound=True,
                timestamp__gt=msg.timestamp,
            ).order_by("timestamp")
        )
        outbound_count = len(outbound)

        if outbound_count <= 1:
            status = EvalRunTask.Status.PASSED
            summary = (
                "No outbound replies after prompt."
                if outbound_count == 0
                else "Single outbound reply after prompt."
            )
        else:
            status = EvalRunTask.Status.FAILED
            summary = f"Agent sent {outbound_count} outbound messages; expected 0 or 1."

        artifacts = {"message": outbound[0]} if outbound else {}
        self.record_task_result(
            run_id,
            None,
            status,
            task_name="verify_outbound_count",
            observed_summary=summary,
            artifacts=artifacts,
        )

        if status == EvalRunTask.Status.FAILED:
            return

        # Task 3: Judge whether the (optional) reply is over-eager/pushy
        self.record_task_result(run_id, None, EvalRunTask.Status.RUNNING, task_name="verify_reply_neediness")

        if not outbound:
            self.record_task_result(
                run_id,
                None,
                EvalRunTask.Status.PASSED,
                task_name="verify_reply_neediness",
                observed_summary="No reply to evaluate; no follow-up is ideal for this prompt.",
            )
            return

        reply = outbound[0].body or ""
        question = (
            "A user said they will reach out later and asked for no follow-ups. "
            "Is this reply appropriate (brief acknowledgement only) or over-eager/pushy "
            "in trying to continue the conversation?"
        )
        choice, reasoning = self.llm_judge(
            question=question,
            context=f"Assistant reply:\n{reply}",
            options=["Appropriate", "Over-eager"],
        )

        if choice == "Appropriate":
            status = EvalRunTask.Status.PASSED
            summary = f"Reply acceptable. Reasoning: {reasoning}"
        else:
            status = EvalRunTask.Status.FAILED
            summary = f"Reply considered over-eager. Reasoning: {reasoning}"

        self.record_task_result(
            run_id,
            None,
            status,
            task_name="verify_reply_neediness",
            observed_summary=summary,
            artifacts={"message": outbound[0]},
        )
