from __future__ import annotations

import logging

from app.core.api.domain.events.client_event import ClientEventRecord
from app.core.api.infrastructure.streaming.sse_event_channel import SseEventChannel
from app.infra.observability.request_trace_logger import RequestTraceLogger
from app.schemas.client_events import ClientEventType

LOGGER = logging.getLogger(__name__)


class RuntimeEventPublisher:
    def __init__(self, channel: SseEventChannel, trace_logger: RequestTraceLogger) -> None:
        self._channel = channel
        self._trace_logger = trace_logger

    async def publish_status(self, request_id: str, source: str, text: str, payload: dict | None = None) -> None:
        LOGGER.warning(
            "publish status: request_id=%s source=%s text=%s payload_keys=%s",
            request_id,
            source,
            text,
            sorted(list((payload or {}).keys())),
        )
        await self._publish(request_id, ClientEventType.STATUS, source, text, payload)

    async def publish_user(self, request_id: str, source: str, text: str, payload: dict | None = None) -> None:
        LOGGER.warning(
            "publish user: request_id=%s source=%s text_len=%s payload_keys=%s",
            request_id,
            source,
            len(text or ""),
            sorted(list((payload or {}).keys())),
        )
        await self._publish(request_id, ClientEventType.USER, source, text, payload)

    async def _publish(
        self,
        request_id: str,
        event_type: ClientEventType,
        source: str,
        text: str,
        payload: dict | None = None,
    ) -> None:
        event = ClientEventRecord(
            request_id=request_id,
            type=event_type,
            source=source,
            text=text,
            payload=payload or {},
        )
        self._trace_logger.log_event(event)
        await self._channel.publish(event)
