"""Optional utility-model critic for premature final answers (parent agent loop only)."""
from __future__ import annotations

import logging
import re

_log = logging.getLogger(__name__)

_FAIL_RE = re.compile(r"^FAIL\s*:\s*(.+)$", re.IGNORECASE)

MAX_GOAL_CHARS = 1200
MAX_TOOLS_TOTAL_CHARS = 2400
MAX_PROPOSED_CHARS = 2400


def _trim(text: str, limit: int) -> str:
    raw = (text or "").strip()
    if len(raw) > limit:
        return raw[:limit] + "\n[truncated]"
    return raw


def maybe_critique_final_answer_continuation(
    *,
    user_goal_excerpt: str,
    recent_tool_excerpt: str,
    proposed_assistant_text: str,
) -> str | None:
    """Return a neutral continuation `user` message body if the critic says FAIL, else None."""
    prompt = (
        "You are a conservative completion critic.\n"
        "The main assistant ended this turn with prose only (no tool call).\n"
        "Return exactly one line:\n"
        "- PASS\n"
        "- FAIL: <short reason>\n"
        "FAIL only when there is a clear mismatch between assistant claims and recent tool evidence.\n"
        "Mark FAIL when the reply claims completion/success (done/saved/rendered/created/completed) "
        "but recent tool output still shows errors, policy blocks, timeouts, validation failures, "
        "not-found/project-missing states, or missing required evidence.\n"
        "Mark FAIL when the reply cites concrete output paths/files/URLs/artifacts that are not "
        "grounded in the recent tool output.\n"
        "If uncertain, PASS.\n\n"
        f"user_goal:\n{_trim(user_goal_excerpt, MAX_GOAL_CHARS)}\n\n"
        f"recent_tools:\n{_trim(recent_tool_excerpt, MAX_TOOLS_TOTAL_CHARS)}\n\n"
        f"assistant_reply:\n{_trim(proposed_assistant_text, MAX_PROPOSED_CHARS)}"
    )

    try:
        from utility_model import utility_complete

        result = utility_complete(
            [{"role": "user", "content": prompt}],
            max_tokens=80,
            temperature=0.0,
            activity_operation="completion_critic",
        )
    except Exception:
        return None
    if not result:
        return None

    first = (result or "").strip().splitlines()[0].strip()
    if first.upper() == "PASS":
        return None

    m = _FAIL_RE.match(first)
    if not m:
        return None

    reason = (m.group(1) or "").strip()[:240]
    if reason:
        _log.debug("completion_critic FAIL: %s", reason)
    return (
        "The harness asks you to verify your last reply against the recent tool results above. "
        "If any tool failed, was blocked, or did not return the evidence you cited, say so plainly "
        "and continue with an allowed tool or ask the user for the next step. "
        "If the reply already matches the tool evidence, answer briefly with that evidence."
    )
