"""Synchronous WebSocket broadcast helper for Celery workers.

Celery tasks run outside the FastAPI event loop. This module provides a
sync Redis publish so tasks can notify connected clients without asyncio.
"""
import traceback
from datetime import datetime

import redis as sync_redis

from ..core.config import settings
from ..core.logging import get_logger
from ..services.websocket import JobStatusUpdate

logger = get_logger(__name__)


def broadcast_status_update(
    job_id: str,
    status: str,
    job_title: str | None = None,
    message: str | None = None,
    progress: int | None = None,
) -> None:
    """Publish a job-status event to Redis so WebSocket subscribers receive it.

    Swallows all exceptions — a broadcast failure must never abort a task.
    """
    try:
        update = JobStatusUpdate(
            job_id=job_id,
            status=status,
            updated_at=datetime.utcnow(),
            job_title=job_title,
            message=message,
            progress=progress,
        )
        payload = update.model_dump_json()

        redis_client = sync_redis.Redis.from_url(
            settings.redis_url,
            encoding="utf-8",
            decode_responses=True,
        )
        try:
            redis_client.publish("job_status_updates", payload)
            redis_client.publish(f"job_status_updates:{job_id}", payload)
        finally:
            redis_client.close()

        logger.info("Broadcast status update job=%s status=%s", job_id, status)

    except Exception:
        logger.error(
            "Failed to broadcast status update job=%s\n%s", job_id, traceback.format_exc()
        )
