from __future__ import annotations

import asyncio
from types import SimpleNamespace

from app.agents.faturas_agent import FaturasAgent
from app.domain.contas.workflow_actions import build_contas_workflow_actions
from contas_mcp.servers.contas_mcp_server import main as mcp_main


def test_invoice_explanation_handoff_action_is_structural_and_uses_configured_message():
    class Service:
        pass

    action = build_contas_workflow_actions(Service()).get("preparar_handoff_invoice_explanation")
    result = action(
        {
            "mensagem": "Para continuar com a sua solicitação, aguarde um instante.",
            "reason": "invoice_explanation_not_resolved",
        },
        {"input": {}},
    )
    assert result["mensagem"] == "Para continuar com a sua solicitação, aguarde um instante."
    assert result["session_control"] == "HUMAN_HANDOFF"
    assert result["human_handoff_requested"] is True
    assert result["handoff"] is True
    assert result["session_ended"] is True
    assert result["terminal_status"] == "human_handoff"


def test_result_payload_promotes_invoice_explanation_handoff_control():
    result = {
        "execution_id": "exec-1",
        "status": "COMPLETED",
        "output": {
            "handoff_pos_explicacao_nao": {
                "success": True,
                "mensagem": "Para continuar com a sua solicitação, aguarde um instante.",
                "session_control": "HUMAN_HANDOFF",
                "handoff_reason": "invoice_explanation_not_resolved",
            }
        },
        "state": {"current_node": "handoff_pos_explicacao_nao"},
        "trace": [{"node": "handoff_pos_explicacao_nao", "status": "COMPLETED"}],
    }
    payload = mcp_main._result_payload(result, workflow_name="invoice_explanation")
    assert payload["mensagem"] == "Para continuar com a sua solicitação, aguarde um instante."
    assert payload["session_control"] == "HUMAN_HANDOFF"
    assert payload["human_handoff_requested"] is True
    assert payload["handoff"] is True
    assert payload["session_ended"] is True


def test_faturas_agent_promotes_handoff_from_tool_context_to_graph_state():
    context = [{
        "tool_name": "retomar_workflow",
        "ok": True,
        "result": {
            "workflow_name": "invoice_explanation",
            "status": "COMPLETED",
            "mensagem": "Para continuar com a sua solicitação, aguarde um instante.",
            "session_control": "HUMAN_HANDOFF",
            "human_handoff_requested": True,
            "session_ended": True,
            "terminal_status": "human_handoff",
            "handoff_reason": "invoice_explanation_not_resolved",
        },
    }]
    patch = FaturasAgent._handoff_patch_from_tool_context(context)
    assert patch == {
        "session_control": "HUMAN_HANDOFF",
        "human_handoff_requested": True,
        "session_ended": True,
        "terminal_status": "human_handoff",
        "handoff_reason": "invoice_explanation_not_resolved",
    }


def test_completed_terminal_workflow_short_circuits_llm_composition_directive():
    agent = FaturasAgent.__new__(FaturasAgent)
    context = [{
        "tool_name": "retomar_workflow",
        "ok": True,
        "result": {
            "status": "COMPLETED",
            "workflow_name": "generic_workflow",
            # Earlier node still carries a composition directive. It must not win
            # over the terminal last node.
            "requires_llm_composition": True,
            "response_instruction": "Componha uma nova resposta.",
            "output": {
                "formatar": {
                    "requires_llm_composition": True,
                    "mensagem": "mensagem anterior",
                },
                "final": {
                    "mensagem": "Encaminhando para atendimento humano.",
                    "session_control": "HUMAN_HANDOFF",
                    "handoff": True,
                    "session_ended": True,
                    "terminal_status": "human_handoff",
                },
            },
            "state": {"current_node": "final"},
        },
    }]
    answer = agent.build_direct_mcp_answer({}, context, agent_label="AnyAgent")
    assert answer == "Encaminhando para atendimento humano."


def test_result_payload_promotes_generic_terminal_last_node_contract():
    result = {
        "execution_id": "exec-generic",
        "status": "COMPLETED",
        "output": {
            "final": {
                "mensagem": "Sessão encerrada.",
                "session_control": "END_SESSION",
                "session_ended": True,
                "terminal_status": "done",
            }
        },
        "state": {"current_node": "final"},
        "trace": [{"node": "final", "status": "COMPLETED"}],
    }
    payload = mcp_main._result_payload(result, workflow_name="generic_example")
    assert payload["terminal"] is True
    assert payload["terminal_action"] == "end_session"
    assert payload["mensagem"] == "Sessão encerrada."
    assert payload["session_ended"] is True
