from fastapi import Request
from fastapi.responses import StreamingResponse
import asyncio
import json
from typing import AsyncGenerator
from app.redis_client import redis_client


async def event_generator() -> AsyncGenerator[str, None]:
    pubsub = redis_client.pubsub()
    pubsub.subscribe("events")
    
    try:
        while True:
            message = pubsub.get_message(timeout=1)
            if message and message["type"] == "message":
                data = json.loads(message["data"])
                yield f"data: {json.dumps(data)}\n\n"
            await asyncio.sleep(0.1)
    except asyncio.CancelledError:
        pubsub.unsubscribe("events")
        raise


async def sse_endpoint(request: Request):
    return StreamingResponse(
        event_generator(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no"
        }
    )


def publish_event(event_type: str, data: dict):
    redis_client.publish("events", json.dumps({
        "type": event_type,
        "data": data,
        "timestamp": str(asyncio.get_event_loop().time())
    }))
