"""Roomkit API endpoints for meeting-room (SIP) device integration."""

from logging import getLogger

from rest_framework import decorators, viewsets
from rest_framework import (
    exceptions as drf_exceptions,
)
from rest_framework import (
    response as drf_response,
)
from rest_framework import (
    status as drf_status,
)

from core import analytics, models
from core.api import permissions, throttling
from core.api.feature_flag import FeatureFlag
from core.services.sip_management import SIPException, SIPManagement

from . import authentication, serializers

logger = getLogger(__name__)


class RoomKitViewSet(viewsets.ViewSet):
    """Server-to-server API endpoints for the roomkit integration.

    Groups all interactions between roomkit (SIP) devices and the backend,
    brokered by the LiveKit SIP module. All endpoints are authenticated
    with the roomkit server-to-server tokens.
    """

    authentication_classes = [authentication.ServerToServerAuthentication]
    permission_classes = [permissions.IsAuthenticated]

    @decorators.action(
        detail=False,
        methods=["post"],
        url_path="join",
        throttle_classes=[throttling.RoomKitJoinRateThrottle],
    )
    @FeatureFlag.require("roomkit")
    def join(self, request):
        """Prepare a room for a meeting-room (SIP) device joining by PIN code.

        Called by the LiveKit SIP module when a meeting-room device dials in
        with a PIN code before any WebRTC participant has joined. Resolves the
        room by PIN and creates its SIP dispatch rule, so the device can enter
        without waiting for a WebRTC user.

        The webhook-based creation path is kept: both converge on the same rule
        through the shared SIPManagement.
        """

        serializer = serializers.RoomKitJoinSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        try:
            room = models.Room.objects.get(
                pin_code=serializer.validated_data["pin_code"]
            )
        except models.Room.DoesNotExist as e:
            raise drf_exceptions.NotFound("No room found for this PIN code.") from e

        try:
            created = SIPManagement().ensure_dispatch_rule(room)
        except SIPException as e:
            raise drf_exceptions.APIException("Could not create dispatch rule.") from e

        analytics.capture(
            request.user,
            analytics.AnalyticsEvent.ROOMKIT_JOINED,
            {
                "room_id": str(room.pk),
                "dispatch_rule_created": created,
            },
        )

        logger.info(
            "Roomkit join requested: room_id=%s, dispatch_rule_created=%s",
            room.id,
            created,
        )

        return drf_response.Response(
            {"status": "success"},
            status=drf_status.HTTP_200_OK,
        )
