from django.db.models import Count, Q
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.parsers import JSONParser, MultiPartParser, FormParser
from drf_spectacular.utils import extend_schema, OpenApiParameter

from apps.core.permissions import HasMenuPermission

from .models import (
    Event, EventTemplate, InvitationTemplate, EventInvitation, EventTeam,
    EventSpeaker, EventScheduleItem, EventRegistration, EventMedia, EventDocument, EventLog,
    RegistrationForm, RegistrationFormField, RegistrationFormSubmission,
    EventBlocklist, EventSettings, OfficeCalendarEntry,
)
from .serializers import (
    EventSerializer, EventTemplateSerializer, InvitationTemplateSerializer, EventInvitationSerializer,
    EventTeamSerializer, EventSpeakerSerializer, EventScheduleItemSerializer,
    EventRegistrationSerializer, EventMediaSerializer, EventDocumentSerializer, EventLogSerializer,
    RegistrationFormSerializer, RegistrationFormFieldSerializer, RegistrationFormSubmissionSerializer,
    EventBlocklistSerializer, EventSettingsSerializer, OfficeCalendarEntrySerializer,
)


def _notify_event(user, *, title, message, link="", priority="medium", related_user=None):
    """Fire an in-app event notification; never break the request on failure."""
    if not user:
        return
    try:
        from apps.notifications.handler import NotificationHandler
        NotificationHandler.send(
            user=user,
            title=title,
            message=message,
            notification_type="event",
            priority=priority,
            icon="calendar",
            link=link,
            related_user=related_user,
            broadcast=True,
        )
    except Exception:
        pass


class EventViewSet(viewsets.ModelViewSet):
    """ViewSet for Event management."""
    rbac_domain = "events"
    queryset = Event.objects.select_related("organizer")
    serializer_class = EventSerializer
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    @extend_schema(
        parameters=[
            OpenApiParameter(name="status", type=str, description="Filter by status"),
            OpenApiParameter(name="event_type", type=str, description="Filter by event type"),
            OpenApiParameter(name="organizer", type=str, description="Filter by organizer ID"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

    def perform_create(self, serializer):
        serializer.save(organizer=self.request.user)

    @extend_schema(
        responses={200: EventTeamSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="teams")
    def teams(self, request, pk=None):
        """Get or create team members for a specific event."""
        if request.method == "GET":
            teams = EventTeam.objects.filter(event_id=pk).select_related("user", "event").order_by("-joined_at")
            serializer = EventTeamSerializer(teams, many=True)
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventTeamSerializer(data={**request.data, "event": pk})
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventSpeakerSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="speakers")
    def speakers(self, request, pk=None):
        """Get or create speakers for a specific event."""
        if request.method == "GET":
            speakers = EventSpeaker.objects.filter(event_id=pk).select_related("event", "contact").order_by("start_time", "created_at")
            serializer = EventSpeakerSerializer(speakers, many=True, context={"request": request})
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventSpeakerSerializer(data={**request.data, "event": pk}, context={"request": request})
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventScheduleItemSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="schedule")
    def schedule(self, request, pk=None):
        """Get or create schedule items for a specific event."""
        if request.method == "GET":
            items = EventScheduleItem.objects.filter(event_id=pk).select_related("event", "speaker").order_by("start_time", "track")
            serializer = EventScheduleItemSerializer(items, many=True)
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventScheduleItemSerializer(data={**request.data, "event": pk})
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventRegistrationSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="registrations")
    def registrations(self, request, pk=None):
        """Get or create registrations for a specific event."""
        if request.method == "GET":
            regs = EventRegistration.objects.filter(event_id=pk).select_related("event", "contact").order_by("-registration_date")
            serializer = EventRegistrationSerializer(regs, many=True)
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventRegistrationSerializer(data={**request.data, "event": pk})
            if serializer.is_valid():
                reg = serializer.save()
                # Notify the event organizer of a new registration.
                event = reg.event
                if event and event.organizer_id:
                    _notify_event(
                        event.organizer,
                        title="New registration",
                        message=f"{reg.name} registered for “{event.name}”.",
                        link=f"/events/{event.id}",
                        priority="low",
                    )
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventInvitationSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="invitations")
    def invitations(self, request, pk=None):
        """Get or create invitations for a specific event."""
        if request.method == "GET":
            invites = EventInvitation.objects.filter(event_id=pk).select_related("event", "contact", "invited_by").order_by("-created_at")
            serializer = EventInvitationSerializer(invites, many=True)
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventInvitationSerializer(data={**request.data, "event": pk})
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventMediaSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="media")
    def media(self, request, pk=None):
        """Get or create media for a specific event."""
        if request.method == "GET":
            media = EventMedia.objects.filter(event_id=pk).select_related("event", "uploaded_by").order_by("-created_at")
            serializer = EventMediaSerializer(media, many=True, context={"request": request})
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventMediaSerializer(data=request.data, context={"request": request})
            if serializer.is_valid():
                serializer.save(
                    event_id=pk,
                    uploaded_by=request.user if request.user.is_authenticated else None,
                )
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventDocumentSerializer(many=True)}
    )
    @action(detail=True, methods=["get", "post"], url_path="documents")
    def documents(self, request, pk=None):
        """Get or create documents for a specific event."""
        if request.method == "GET":
            docs = EventDocument.objects.filter(event_id=pk).select_related("event", "uploaded_by").order_by("-created_at")
            serializer = EventDocumentSerializer(docs, many=True, context={"request": request})
            return Response(serializer.data)
        elif request.method == "POST":
            serializer = EventDocumentSerializer(data=request.data, context={"request": request})
            if serializer.is_valid():
                serializer.save(
                    event_id=pk,
                    uploaded_by=request.user if request.user.is_authenticated else None,
                )
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)

    @extend_schema(
        responses={200: EventLogSerializer(many=True)}
    )
    @action(detail=True, methods=["get"], url_path="logs")
    def logs(self, request, pk=None):
        """Get activity logs for a specific event."""
        logs = EventLog.objects.filter(event_id=pk).select_related("event", "actor").order_by("-created_at")
        serializer = EventLogSerializer(logs, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="mc-script")
    def mc_script(self, request, pk=None):
        """Generate an MC run-of-show JSON from the event's schedule items."""
        event = self.get_object()
        items = (
            EventScheduleItem.objects
            .filter(event_id=pk)
            .select_related("speaker")
            .order_by("start_time", "track")
        )
        sessions = []
        for it in items:
            speaker = it.speaker_name or (it.speaker.name if it.speaker_id else "")
            time_range = ""
            if it.start_time and it.end_time:
                time_range = f"{it.start_time.strftime('%H:%M')} – {it.end_time.strftime('%H:%M')}"
            sessions.append({
                "time": time_range,
                "title": it.title,
                "type": it.session_type,
                "speaker": speaker or None,
                "script": it.description or "",
            })
        return Response({
            "event": event.name,
            "generated_from": "schedule",
            "sessions": sessions,
        })

    @action(detail=True, methods=["get"], url_path="teleprompter-script")
    def teleprompter_script(self, request, pk=None):
        """Generate a teleprompter JSON from the event's schedule and speakers."""
        event = self.get_object()
        items = (
            EventScheduleItem.objects
            .filter(event_id=pk)
            .select_related("speaker")
            .order_by("start_time", "track")
        )
        speakers = {
            s.name: s
            for s in EventSpeaker.objects.filter(event_id=pk)
        }
        sections = []
        for it in items:
            speaker_name = it.speaker_name or (it.speaker.name if it.speaker_id else "")
            lines = [it.title]
            if speaker_name:
                sp = speakers.get(speaker_name)
                role = ", ".join(filter(None, [sp.title, sp.organization])) if sp else ""
                lines.append(f"Mempersilakan {speaker_name}{(' — ' + role) if role else ''}.")
            if it.description:
                lines.append(it.description)
            sections.append({
                "heading": it.title,
                "body": "\n\n".join(lines),
            })
        return Response({
            "title": event.name,
            "generated_from": "schedule+speakers",
            "sections": sections,
        })


class EventTemplateViewSet(viewsets.ModelViewSet):
    """ViewSet for EventTemplate management."""
    rbac_domain = "events"
    queryset = EventTemplate.objects.select_related("created_by")
    serializer_class = EventTemplateSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event_type", type=str, description="Filter by event type"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class InvitationTemplateViewSet(viewsets.ModelViewSet):
    """ViewSet for InvitationTemplate management."""
    rbac_domain = "events"
    queryset = InvitationTemplate.objects.select_related("created_by")
    serializer_class = InvitationTemplateSerializer
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    @extend_schema(
        parameters=[
            OpenApiParameter(name="category", type=str, description="Filter by category"),
        ]
    )
    def list(self, request, *args, **kwargs):
        qs = self.get_queryset()
        category = request.query_params.get("category")
        if category:
            qs = qs.filter(category=category)
        serializer = self.get_serializer(qs, many=True)
        return Response(serializer.data)

    def perform_create(self, serializer):
        user = self.request.user if self.request.user.is_authenticated else None
        serializer.save(created_by=user)


class EventInvitationViewSet(viewsets.ModelViewSet):
    """ViewSet for EventInvitation management."""
    rbac_domain = "events"
    queryset = EventInvitation.objects.select_related("event", "contact", "invited_by")
    serializer_class = EventInvitationSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="status", type=str, description="Filter by status"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventTeamViewSet(viewsets.ModelViewSet):
    """ViewSet for EventTeam management."""
    rbac_domain = "events"
    queryset = EventTeam.objects.select_related("event", "user")
    serializer_class = EventTeamSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventSpeakerViewSet(viewsets.ModelViewSet):
    """ViewSet for EventSpeaker management."""
    rbac_domain = "events"
    queryset = EventSpeaker.objects.select_related("event", "contact")
    serializer_class = EventSpeakerSerializer
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    def get_serializer_context(self):
        ctx = super().get_serializer_context()
        ctx["request"] = self.request
        return ctx

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventScheduleItemViewSet(viewsets.ModelViewSet):
    """ViewSet for EventScheduleItem management."""
    rbac_domain = "events"
    queryset = EventScheduleItem.objects.select_related("event", "speaker")
    serializer_class = EventScheduleItemSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="track", type=str, description="Filter by track"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventRegistrationViewSet(viewsets.ModelViewSet):
    """ViewSet for EventRegistration management."""
    rbac_domain = "events"
    queryset = EventRegistration.objects.select_related("event", "contact")
    serializer_class = EventRegistrationSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="status", type=str, description="Filter by status"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

    def perform_update(self, serializer):
        from django.utils import timezone
        new_status = serializer.validated_data.get("status")
        extra = {}
        if new_status == "checked_in" and not serializer.instance.check_in_time:
            extra["check_in_time"] = timezone.now()
        elif new_status and new_status != "checked_in":
            extra["check_in_time"] = None
        serializer.save(**extra)


class EventMediaViewSet(viewsets.ModelViewSet):
    """ViewSet for EventMedia management."""
    rbac_domain = "events"
    queryset = EventMedia.objects.select_related("event", "uploaded_by")
    serializer_class = EventMediaSerializer
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    def get_serializer_context(self):
        ctx = super().get_serializer_context()
        ctx["request"] = self.request
        return ctx

    @action(detail=True, methods=["post"], url_path="set-cover")
    def set_cover(self, request, pk=None):
        """Mark this media as the event cover; unmark others."""
        try:
            media = EventMedia.objects.get(pk=pk)
        except EventMedia.DoesNotExist:
            return Response({"detail": "Not found"}, status=404)
        EventMedia.objects.filter(event_id=media.event_id).exclude(pk=media.pk).update(is_cover=False)
        media.is_cover = True
        media.save(update_fields=["is_cover"])
        return Response(EventMediaSerializer(media, context={"request": request}).data)

    @action(detail=True, methods=["post"], url_path="unset-cover")
    def unset_cover(self, request, pk=None):
        try:
            media = EventMedia.objects.get(pk=pk)
        except EventMedia.DoesNotExist:
            return Response({"detail": "Not found"}, status=404)
        media.is_cover = False
        media.save(update_fields=["is_cover"])
        return Response(EventMediaSerializer(media, context={"request": request}).data)

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="file_type", type=str, description="Filter by file type"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventDocumentViewSet(viewsets.ModelViewSet):
    """ViewSet for EventDocument management."""
    rbac_domain = "events"
    queryset = EventDocument.objects.select_related("event", "uploaded_by")
    serializer_class = EventDocumentSerializer
    parser_classes = [JSONParser, MultiPartParser, FormParser]

    def get_serializer_context(self):
        ctx = super().get_serializer_context()
        ctx["request"] = self.request
        return ctx

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="category", type=str, description="Filter by category"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


class EventLogViewSet(viewsets.ModelViewSet):
    """ViewSet for EventLog management."""
    rbac_domain = "events"
    queryset = EventLog.objects.select_related("event", "actor")
    serializer_class = EventLogSerializer

    @extend_schema(
        parameters=[
            OpenApiParameter(name="event", type=str, description="Filter by event ID"),
            OpenApiParameter(name="log_type", type=str, description="Filter by log type"),
        ]
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)


def _annotated_form_queryset():
    return (
        RegistrationForm.objects
        .select_related("event", "project", "created_by")
        .prefetch_related("fields")
        .annotate(
            submission_count=Count("submissions", distinct=True),
            pending_count=Count("submissions", filter=Q(submissions__status="pending"), distinct=True),
            reviewed_count=Count("submissions", filter=Q(submissions__status="reviewed"), distinct=True),
            approved_count=Count("submissions", filter=Q(submissions__status="approved"), distinct=True),
        )
    )


class RegistrationFormViewSet(viewsets.ModelViewSet):
    """ViewSet for RegistrationForm (form-builder schema)."""
    rbac_domain = "events"
    serializer_class = RegistrationFormSerializer
    permission_classes=[IsAuthenticated, HasMenuPermission]

    def get_queryset(self):
        qs = _annotated_form_queryset()
        source = self.request.query_params.get("source")
        status_param = self.request.query_params.get("status")
        event_id = self.request.query_params.get("event")
        project_id = self.request.query_params.get("project")
        if source:
            qs = qs.filter(source=source)
        if status_param:
            qs = qs.filter(status=status_param)
        if event_id:
            qs = qs.filter(event_id=event_id)
        if project_id:
            qs = qs.filter(project_id=project_id)
        return qs

    def perform_create(self, serializer):
        user = self.request.user if self.request.user.is_authenticated else None
        serializer.save(created_by=user)

    @action(detail=True, methods=["get", "post", "put"], url_path="fields")
    def fields(self, request, pk=None):
        """GET list, POST single field, PUT replaces all (bulk)."""
        form = self.get_object()
        if request.method == "GET":
            qs = form.fields.all()
            return Response(RegistrationFormFieldSerializer(qs, many=True).data)
        if request.method == "POST":
            ser = RegistrationFormFieldSerializer(data={**request.data, "form": form.id})
            ser.is_valid(raise_exception=True)
            ser.save(form=form)
            return Response(ser.data, status=201)
        # PUT: replace all fields atomically
        items = request.data if isinstance(request.data, list) else request.data.get("fields", [])
        form.fields.all().delete()
        created = []
        for idx, item in enumerate(items):
            data = {**item}
            data["form"] = form.id
            data.setdefault("order", idx)
            ser = RegistrationFormFieldSerializer(data=data)
            ser.is_valid(raise_exception=True)
            ser.save(form=form)
            created.append(ser.data)
        return Response(created, status=200)

    @action(detail=True, methods=["get"], url_path="submissions")
    def submissions(self, request, pk=None):
        form = self.get_object()
        qs = form.submissions.select_related("reviewed_by").all()
        status_param = request.query_params.get("status")
        if status_param:
            qs = qs.filter(status=status_param)
        return Response(RegistrationFormSubmissionSerializer(qs, many=True).data)


class RegistrationFormFieldViewSet(viewsets.ModelViewSet):
    """ViewSet for individual fields (CRUD by id)."""
    rbac_domain = "events"
    queryset = RegistrationFormField.objects.select_related("form")
    serializer_class = RegistrationFormFieldSerializer
    permission_classes=[IsAuthenticated, HasMenuPermission]


class RegistrationFormSubmissionViewSet(viewsets.ModelViewSet):
    """ViewSet for submissions. List/retrieve/update auth-only; create allowed via PublicRegistrationFormView."""
    rbac_domain = "events"
    queryset = RegistrationFormSubmission.objects.select_related("form", "reviewed_by")
    serializer_class = RegistrationFormSubmissionSerializer
    permission_classes=[IsAuthenticated, HasMenuPermission]

    def get_queryset(self):
        qs = super().get_queryset()
        form_id = self.request.query_params.get("form")
        status_param = self.request.query_params.get("status")
        if form_id:
            qs = qs.filter(form_id=form_id)
        if status_param:
            qs = qs.filter(status=status_param)
        return qs

    def perform_update(self, serializer):
        from django.utils import timezone
        new_status = serializer.validated_data.get("status")
        extra = {}
        if new_status in ("reviewed", "approved", "rejected"):
            extra["reviewed_at"] = timezone.now()
            if self.request.user.is_authenticated:
                extra["reviewed_by"] = self.request.user
        serializer.save(**extra)


class PublicRegistrationFormViewSet(viewsets.ViewSet):
    """Public read + submit endpoint. Anonymous sees only published forms.
    Authenticated users can preview drafts.
    """
    rbac_domain = "events"
    permission_classes = [AllowAny]

    def _get_form(self, pk):
        from django.core.exceptions import ValidationError
        try:
            return (
                RegistrationForm.objects
                .select_related("event", "project")
                .prefetch_related("fields")
                .get(pk=pk)
            )
        except (RegistrationForm.DoesNotExist, ValidationError, ValueError):
            return None

    def retrieve(self, request, pk=None):
        form = self._get_form(pk)
        if form is None:
            return Response({"detail": "Not found"}, status=404)
        if form.status != "published" and not request.user.is_authenticated:
            return Response({"detail": "Form is not published"}, status=404)
        return Response(RegistrationFormSerializer(form).data)

    @action(detail=True, methods=["post"], url_path="submit")
    def submit(self, request, pk=None):
        form = self._get_form(pk)
        if form is None:
            return Response({"detail": "Not found"}, status=404)
        if form.status != "published":
            return Response({"detail": "Form is not accepting submissions"}, status=400)
        email = (request.data.get("submitter_email") or "").strip().lower()
        data = {
            "form": form.id,
            "submitter_name": request.data.get("submitter_name", ""),
            "submitter_email": email,
            "answers": request.data.get("answers", {}),
        }
        ser = RegistrationFormSubmissionSerializer(data=data)
        ser.is_valid(raise_exception=True)
        ip = request.META.get("HTTP_X_FORWARDED_FOR", "").split(",")[0].strip() or request.META.get("REMOTE_ADDR")

        # Auto-reject if email is on blocklist (global or form-event scoped),
        # unless the event opted to bypass the blocklist in its settings.
        extra = {"form": form, "ip_address": ip or None}
        bypass = bool(form.event and (form.event.settings or {}).get("bypass_blocklist"))
        if email and not bypass:
            scope_filter = Q(event__isnull=True)
            if form.event_id:
                scope_filter |= Q(event_id=form.event_id)
            block = EventBlocklist.objects.filter(scope_filter, email__iexact=email).first()
            if block:
                extra["status"] = "rejected"
                extra["auto_blocked"] = True
                extra["block_reason"] = block.reason or "Email is on blocklist"
        ser.save(**extra)
        return Response(ser.data, status=201)


class EventBlocklistViewSet(viewsets.ModelViewSet):
    """ViewSet for event blocklist management."""
    rbac_domain = "events"
    queryset = EventBlocklist.objects.select_related("event", "blocked_by")
    serializer_class = EventBlocklistSerializer
    permission_classes=[IsAuthenticated, HasMenuPermission]

    def get_queryset(self):
        qs = super().get_queryset()
        event_id = self.request.query_params.get("event")
        scope = self.request.query_params.get("scope")
        if event_id:
            qs = qs.filter(event_id=event_id)
        if scope == "global":
            qs = qs.filter(event__isnull=True)
        elif scope == "event":
            qs = qs.filter(event__isnull=False)
        return qs

    def perform_create(self, serializer):
        user = self.request.user if self.request.user.is_authenticated else None
        email = (serializer.validated_data.get("email") or "").strip().lower()
        serializer.save(blocked_by=user, email=email)


class OfficeCalendarEntryViewSet(viewsets.ModelViewSet):
    """ViewSet for org-wide calendar entries (holidays / office events)."""
    rbac_domain = "events"
    queryset = OfficeCalendarEntry.objects.all()
    serializer_class = OfficeCalendarEntrySerializer
    permission_classes = [IsAuthenticated, HasMenuPermission]
    pagination_class = None  # full list — calendar renders every entry

    def get_queryset(self):
        qs = super().get_queryset()
        entry_type = self.request.query_params.get("entry_type")
        if entry_type:
            qs = qs.filter(entry_type=entry_type)
        return qs

    @action(detail=False, methods=["get"])
    def export(self, request):
        """Dump all entries as a JSON list (file download)."""
        data = OfficeCalendarEntrySerializer(self.get_queryset(), many=True).data
        response = Response(data)
        response["Content-Disposition"] = 'attachment; filename="office-calendar.json"'
        return response

    @action(detail=False, methods=["post"])
    def import_entries(self, request, *args, **kwargs):
        """Bulk-create entries from a JSON list. `replace=true` clears existing first."""
        payload = request.data
        rows = payload.get("entries") if isinstance(payload, dict) else payload
        if not isinstance(rows, list):
            return Response({"detail": "Expected a JSON list of entries."}, status=400)

        if str(request.query_params.get("replace", "")).lower() in ("1", "true", "yes"):
            self.get_queryset().delete()

        serializer = OfficeCalendarEntrySerializer(data=rows, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"imported": len(serializer.data), "entries": serializer.data}, status=201)


class EventSettingsView(APIView):
    """Singleton endpoint at /api/event-settings/."""
    permission_classes = [IsAuthenticated]

    def get(self, request):
        obj = EventSettings.get_solo()
        return Response(EventSettingsSerializer(obj).data)

    def put(self, request):
        obj = EventSettings.get_solo()
        serializer = EventSettingsSerializer(obj, data=request.data, context={"request": request})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(EventSettingsSerializer(obj).data)
