from __future__ import annotations

import unittest

from app.livekit.adapters.agent_backend import BackendReply
from app.livekit.adapters.fake_remote_ws_adapter import FakeRemoteWSAdapter


class FakeRemoteWSAdapterTests(unittest.IsolatedAsyncioTestCase):
    RESPONSES = (
        "Primeira resposta deterministica com comprimento intermediario",
        "Segunda resposta deterministica preparando a formalizacao",
        "Terceira resposta deterministica encerrando o atendimento",
    )

    async def test_run_returns_mocked_reply_with_transcribed_text(self) -> None:
        adapter = FakeRemoteWSAdapter(
            intro="oi",
            request_context={
                "agent": "oferta",
                "RouterCallKeyDay": "20260329",
                "RouterCallKey": "0001",
                "ANI": "3133334444",
                "GSM": "31999999999",
                "callIdGed": "GED-123",
            },
        )
        await adapter.prepare(True, "PRT-123")

        reply = await adapter.run({"text": "quero detalhes da oferta"})

        self.assertEqual(reply.stage, "ARGUMENTATION")
        self.assertFalse(reply.done)
        self.assertIn("quero detalhes da oferta", reply.text.lower())

    async def test_end_service_once_returns_done_without_endpoint_dependency(self) -> None:
        adapter = FakeRemoteWSAdapter(
            intro="oi",
            request_context={"agent": "conta", "GSM": "5511999999999"},
        )
        await adapter.prepare(True, "PRT-999")

        reply = await adapter.end_service_once()

        self.assertEqual(
            reply,
            BackendReply(
                stage="DONE",
                text="Atendimento simulado de conta encerrado. Obrigado.",
                done=True,
                export_payload={
                    "type": "final",
                    "content": "Atendimento simulado de conta encerrado. Obrigado.",
                    "tool_calls": [],
                    "result": [{"status": "ok", "reason": "fake_done"}],
                },
            ),
        )

    async def test_scripted_responses_are_sequential_and_end_idempotently(self) -> None:
        adapter = FakeRemoteWSAdapter(
            intro="saudacao normal",
            request_context={"agent": "oferta"},
            delay_ms=0,
            responses=self.RESPONSES,
        )
        await adapter.prepare(True, "PRT-SEQUENTIAL")

        first = await adapter.run({"text": "texto do STT que nao influencia a resposta"})
        second = await adapter.run({"text": "outro texto arbitrario reconhecido"})
        third = await adapter.run({"text": "ultimo texto arbitrario reconhecido"})
        repeated = await adapter.run({"text": "texto posterior ao encerramento"})

        self.assertEqual(
            [first.stage, second.stage, third.stage],
            ["ARGUMENTATION", "FORMALIZATION", "DONE"],
        )
        self.assertEqual([first.text, second.text, third.text], list(self.RESPONSES))
        self.assertTrue(third.done)
        self.assertIs(repeated, third)

    async def test_scripted_sequence_is_isolated_per_adapter_session(self) -> None:
        first_call = FakeRemoteWSAdapter(intro="oi", delay_ms=0, responses=self.RESPONSES)
        second_call = FakeRemoteWSAdapter(intro="oi", delay_ms=0, responses=self.RESPONSES)
        await first_call.prepare(True, "PRT-1")
        await second_call.prepare(True, "PRT-2")

        await first_call.run("fala um")
        first_reply_second_call = await second_call.run("fala independente")

        self.assertEqual(first_reply_second_call.text, self.RESPONSES[0])
        self.assertEqual(first_reply_second_call.stage, "ARGUMENTATION")


if __name__ == "__main__":
    unittest.main()
