"""SSE (Server-Sent Events) handler for streaming model updates.

Provides FastAPI endpoints that stream events using the SSE protocol.

⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
"""

from __future__ import annotations

import asyncio
import json
import logging
from collections.abc import AsyncGenerator

from starlette.requests import Request
from starlette.responses import StreamingResponse

from ._generated.event_bus import StreamEvent, event_bus

logger = logging.getLogger(__name__)


async def _sse_event_generator(
    request: Request,
    *,
    model: str | None = None,
    event_types: list[str] | None = None,
    keepalive_interval: int = {{ keepalive_interval }},
) -> AsyncGenerator[str, None]:
    """Generate SSE-formatted event strings.

    Args:
        request: The incoming HTTP request (used to detect disconnection).
        model: Filter to events for this model name only.
        event_types: Filter to these event types only.
        keepalive_interval: Seconds between keepalive pings.

    Yields:
        SSE-formatted event strings.
    """
    subscriber = event_bus.subscribe(model=model, event_types=event_types)

    try:
        async for event in subscriber:
            if await request.is_disconnected():
                break

            data = {
                "model": event.model,
                "event_type": event.event_type,
                "entity_id": event.entity_id,
            }
            if event.payload is not None:
                data["payload"] = event.payload
            if event.metadata:
                data["metadata"] = event.metadata

            yield f"event: {event.model}.{event.event_type}\n"
            yield f"data: {json.dumps(data, default=str)}\n\n"
    except asyncio.CancelledError:
        pass


def create_sse_response(
    request: Request,
    *,
    model: str | None = None,
    event_types: list[str] | None = None,
) -> StreamingResponse:
    """Create an SSE StreamingResponse for the given filter.

    Args:
        request: The incoming HTTP request.
        model: Filter to events for this model name only.
        event_types: Filter to these event types only.

    Returns:
        A StreamingResponse with SSE content type.
    """
    return StreamingResponse(
        _sse_event_generator(request, model=model, event_types=event_types),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no",
        },
    )


__all__ = ["create_sse_response"]
