"""Приёмник webhook-событий LiveKit (без JWT — верификация подписью LiveKit)."""

import logging
from typing import Annotated, Any, cast

from fastapi import APIRouter, BackgroundTasks, Depends, Header, HTTPException, Request, status
from livekit import api
from sqlalchemy import CursorResult
from sqlalchemy.dialects.postgresql import insert as pg_insert
from sqlalchemy.ext.asyncio import AsyncSession

from core.config import get_settings
from core.db import get_session
from models.webhook_event import LivekitWebhookEvent
from services.webhook_handlers import WebhookDispatcher

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/livekit", tags=["livekit"])


@router.post("/webhook")
async def receive_webhook(
    request: Request,
    background: BackgroundTasks,
    session: Annotated[AsyncSession, Depends(get_session)],
    authorization: Annotated[str | None, Header()] = None,
) -> dict[str, str]:
    """Принять, верифицировать и обработать webhook-событие LiveKit.

    Дедупликация по `event.id`: `INSERT ... ON CONFLICT DO NOTHING` в
    `livekit_webhook_events` в одной транзакции с эффектами обработчика —
    при конфликте (дубль) эффекты пропускаются, но ответ всё равно 200.

    Всё, что требует сети (запуск Track Egress), уходит в `background` и
    выполняется уже после ответа: обработчик держит соединение с БД и
    открытую транзакцию, а LiveKit при медленном ответе копит очередь
    доставки и в итоге дропает события (см. `services.egress.run_track_egress`).
    """
    settings = get_settings()
    raw_body = await request.body()

    receiver = api.WebhookReceiver(
        api.TokenVerifier(settings.livekit_api_key, settings.livekit_api_secret)
    )
    try:
        event = receiver.receive(raw_body.decode(), authorization or "")
    except Exception as exc:  # noqa: BLE001 — SDK кидает generic Exception на невалидную подпись
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid_signature"
        ) from exc

    insert_result = cast(
        CursorResult[Any],
        await session.execute(
            pg_insert(LivekitWebhookEvent)
            .values(event_id=event.id, event_type=event.event)
            .on_conflict_do_nothing(index_elements=["event_id"])
        ),
    )
    if insert_result.rowcount == 0:
        # Дубль уже обработанного события — пропускаем эффекты, но отвечаем 200.
        await session.commit()
        return {"status": "duplicate"}

    dispatcher = WebhookDispatcher(session, schedule=background.add_task)
    await dispatcher.dispatch(event)
    await session.commit()
    return {"status": "ok"}
