"""WebSocket integration tests for the terminal client."""

from __future__ import annotations

import asyncio
import json

import pytest
import websockets

from clients.terminal.config import Settings
from clients.terminal.render import Renderer
from clients.terminal.ws_client import NaviWebSocketClient


async def fake_navi_server(websocket: websockets.ServerConnection) -> None:
    """Fake Navi server: echo one message back as stream events."""
    raw = await websocket.recv()
    msg = json.loads(raw)
    assert msg["type"] == "message"

    events = [
        {"type": "session_sync", "session_id": "test-session", "profile_id": "navi_code"},
        {"type": "stream_start"},
        {"type": "stream_delta", "delta": "Echo: "},
        {"type": "stream_delta", "delta": msg["content"]},
        {"type": "stream_end", "content": f"Echo: {msg['content']}"},
    ]
    for ev in events:
        await websocket.send(json.dumps(ev))


@pytest.mark.anyio
async def test_run_one_shot_receives_and_renders_events() -> None:
    stop_event = asyncio.Event()

    async def serve() -> None:
        async with websockets.serve(fake_navi_server, "127.0.0.1", 0) as server:
            port = server.sockets[0].getsockname()[1]
            settings = Settings(base_url=f"http://127.0.0.1:{port}")
            renderer = Renderer()
            client = NaviWebSocketClient("test-session", renderer=renderer)
            client.url = settings.websocket_url("test-session")

            await client.run_one_shot("hello")
            stop_event.set()

    await asyncio.wait_for(serve(), timeout=10.0)
    assert stop_event.is_set()


def test_renderer_session_sync_without_session_id_does_not_crash(capsys) -> None:
    """Regression: session_sync with no session_id must not crash the renderer.

    The server used to send {"type": "session_sync"} without session_id, which
    made render.py do None[:8]. The renderer must tolerate a missing id.
    """
    renderer = Renderer(show_events=True)
    renderer.render({"type": "session_sync"})  # no session_id / profile_id
    out = capsys.readouterr().out
    assert "[session ? | profile unknown]" in out


def test_renderer_session_sync_with_session_id(capsys) -> None:
    """When session_id/profile_id are present they render in the header."""
    renderer = Renderer(show_events=True)
    renderer.render(
        {"type": "session_sync", "session_id": "abcdef1234567890", "profile_id": "navi_code"}
    )
    out = capsys.readouterr().out
    assert "[session abcdef12 | profile navi_code]" in out
