"""VerbalizacaoPrematura — supervisão de promessa feita antes de validação.

Detecta quando o agente usou linguagem de promessa ou afirmou que uma ação
foi concluída antes de validar a viabilidade técnica ou obter confirmação.

Atenção: este rail de SUPERVISÃO é distinto do RevprecRail de OUTPUT (que
detecta promessa de ação financeira futura). Este rail detecta mais amplamente:
promessa de resultado específico, data ou valor antes de confirmação técnica.

Implementa o Protocol ``Rail`` de contracts.py (AT-06.5).
"""
from __future__ import annotations

from agent_framework.llm.structured_output import parse_json_object

import json
import logging

from ...contracts import GuardRailContext, GuardRailLLMClient, RailDecision
from ...llm_adapter import AgentLLMClientAdapter
from ...prompts.shared.supervision_template import build_supervision_prompt

logger = logging.getLogger(__name__)

_CRITERIOS = """\
1. Agente usou linguagem de promessa futura ("vou cancelar", "vou retirar", \
"será creditado", "vou devolver") antes de confirmar que a ação é possível.
2. Agente afirmou que algo "foi feito" ou "foi cancelado" quando na verdade \
a ação ainda está pendente de confirmação (``acao_executada=false``).
3. Agente prometeu data ou valor específico sem validação técnica \
(ex.: "o crédito cai em 2 dias úteis" sem consultar o sistema).
4. Promessas condicionais claras ("se aprovado, será creditado") NÃO são violação.
5. Linguagem de processo em andamento ("estou verificando", "vou checar") \
NÃO é violação — não é promessa de resultado."""

_EXEMPLOS = """\
Exemplo 1 — VIOLAÇÃO:
  Resposta do agente: "Vou cancelar o serviço de streaming agora para você."
  Dados: {"acao_executada": false, "promessa_feita": "Vou cancelar o serviço de streaming agora"}
  Saída: {"violation": true, "confidence": "high", "reason": "Agente prometeu cancelamento antes de executar a ação"}

Exemplo 2 — VIOLAÇÃO:
  Resposta do agente: "O cancelamento já foi feito com sucesso."
  Dados: {"acao_executada": false, "promessa_feita": "O cancelamento já foi feito"}
  Saída: {"violation": true, "confidence": "high", "reason": "Agente afirmou ação concluída quando acao_executada=false"}

Exemplo 3 — NÃO VIOLAÇÃO:
  Resposta do agente: "O cancelamento foi processado com sucesso."
  Dados: {"acao_executada": true, "promessa_feita": "cancelamento processado"}
  Saída: {"violation": false, "confidence": "high", "reason": "Ação foi executada antes da verbalização; confirmação legítima"}

Exemplo 4 — NÃO VIOLAÇÃO:
  Resposta do agente: "Estou verificando sua conta agora."
  Dados: {"acao_executada": false, "promessa_feita": ""}
  Saída: {"violation": false, "confidence": "high", "reason": "Linguagem de processo em andamento, sem promessa de resultado"}

Exemplo 5 — VIOLAÇÃO:
  Resposta do agente: "O crédito de R$ 9,90 cai na sua conta em 2 dias úteis."
  Dados: {"acao_executada": false, "promessa_feita": "crédito em 2 dias úteis"}
  Saída: {"violation": true, "confidence": "high", "reason": "Agente prometeu prazo e valor específicos sem confirmar execução da ação"}"""


class VerbalizacaoPrematura:
    """Rail de supervisão: promessa de resultado antes de validação (AT-06.5).

    ``agent_metadata`` esperado:
        - ``acao_executada`` (bool): se a ação técnica foi de fato executada.
        - ``promessa_feita`` (str): trecho da resposta que contém a promessa.

    Fallback conservador: em caso de falha técnica, retorna ``violation=False``.
    """

    def __init__(self, llm_client: GuardRailLLMClient | None = None) -> None:
        self._client: GuardRailLLMClient = llm_client or AgentLLMClientAdapter()

    @property
    def code(self) -> str:
        return "VERBALIZACAO_PREMATURA"

    @property
    def fallback_text(self) -> str | None:
        return None

    @property
    def regen_flag(self) -> str | None:
        return None

    @property
    def is_soft_alert(self) -> bool:
        return True

    def evaluate(self, context: GuardRailContext) -> RailDecision:
        """Avalia se o agente prometeu resultado antes de validar a viabilidade.

        Args:
            context: GuardRailContext com:
                - ``user_text``: última fala do agente (output a supervisionar).
                - ``conversation_history``: histórico recente da conversa.
                - ``agent_metadata``: ``{"acao_executada": bool,
                  "promessa_feita": str}``.

        Returns:
            RailDecision com ``allowed=False`` quando violação detectada;
            ``allowed=True`` caso contrário ou em falha técnica.
        """
        meta = context.agent_metadata or {}
        historico_formatado = _format_history(context.conversation_history)
        dados_transacao = json.dumps(
            {
                "acao_executada": meta.get("acao_executada", False),
                "promessa_feita": meta.get("promessa_feita", ""),
                "resposta_agente": context.user_text,
            },
            ensure_ascii=False,
        )

        prompt = build_supervision_prompt(
            rail_name="Verbalização Prematura",
            criterios=_CRITERIOS,
            historico=historico_formatado,
            dados_transacao=dados_transacao,
            exemplos=_EXEMPLOS,
        )

        input_vars = {
            "text": context.user_text,
            "prompt": prompt,
            "context": meta,
        }

        try:
            raw = self._client.invoke(self.code, input_vars)
            result: dict = parse_json_object(raw) if isinstance(raw, str) else raw
        except Exception as exc:
            logger.error(
                "verbalizacao_prematura_rail.invoke_error session=%s exc=%r — assuming no violation",
                context.session_id,
                exc,
            )
            return RailDecision(
                allowed=True,
                code=self.code,
                reason="evaluation_error",
            )

        violation = bool(result.get("violation", False))
        reason = result.get("reason", "")
        confidence = result.get("confidence", "")

        if violation:
            logger.warning(
                "verbalizacao_prematura_rail.violation session=%s confidence=%r reason=%r",
                context.session_id,
                confidence,
                reason,
            )
            return RailDecision(
                allowed=True,
                is_soft_alert=True,
                code=self.code,
                reason=reason,
            )

        return RailDecision(
            allowed=True,
            code=self.code,
            reason="no_violation",
        )


def _format_history(history: list[dict]) -> str:
    """Formata o histórico de conversa para inserção no prompt."""
    if not history:
        return "(sem histórico disponível)"
    lines = []
    for turn in history[-10:]:
        role = turn.get("role", "?")
        content = turn.get("content", "")
        role_label = "Cliente" if role == "user" else "Agente"
        lines.append(f"{role_label}: {content}")
    return "\n".join(lines)


__all__ = ["VerbalizacaoPrematura"]
