from __future__ import annotations

import json
import unittest
from types import SimpleNamespace

from routes.sessions import stream_ui_events
from ui_event_bus import UiEventBus


class DummyRequest:
    def __init__(self, chat_id: str) -> None:
        self.query_params = {"chat_id": chat_id}

    async def is_disconnected(self) -> bool:
        return False


class EventsRouteTests(unittest.IsolatedAsyncioTestCase):
    async def test_events_stream_emits_ready_and_published_payload(self) -> None:
        runtime = SimpleNamespace(event_bus=UiEventBus())

        response = await stream_ui_events(DummyRequest("test-chat"), runtime=runtime)
        iterator = response.body_iterator

        first_chunk = await anext(iterator)
        self.assertEqual(first_chunk, ": stream-open\n\n")

        second_chunk = await anext(iterator)
        ready_payload = json.loads(second_chunk.removeprefix("data: ").strip())
        self.assertEqual(ready_payload["type"], "events.ready")
        self.assertEqual(ready_payload["chat_id"], "test-chat")

        await runtime.event_bus.publish(
            {"type": "cards.changed", "chat_id": "test-chat"},
            chat_id="test-chat",
        )

        third_chunk = await anext(iterator)
        event_payload = json.loads(third_chunk.removeprefix("data: ").strip())
        self.assertEqual(event_payload["type"], "cards.changed")
        self.assertEqual(event_payload["chat_id"], "test-chat")

        await iterator.aclose()
