from typing import Any

from rest_framework import generics, permissions
from rest_framework.response import Response
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from apps.calls.filters import NotificationFilter
from apps.calls.services import NotificationService
from apps.calls.serializers import NotificationSerializer
from apps.calls.pagination import UnreadReadPagination


class NotificationListView(generics.ListAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = UnreadReadPagination

    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = NotificationFilter
    search_fields = ['title', 'recipient__username']
    ordering_fields = ['created_at', 'is_read']
    ordering = ['-created_at']

    def __init__(self, **kwargs: Any):
        super().__init__()
        self._filtered_qs = None
        self._unfiltered_qs = None

    def get_queryset(self):
        queryset = NotificationService.list_notifications(self.request.user)

        self._unfiltered_qs = queryset
        return queryset

    @property
    def unfiltered_qs(self):
        return self._unfiltered_qs

class NotificationDetailView(generics.RetrieveAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return NotificationService.list_notifications(self.request.user)

class MarkNotificationReadView(generics.UpdateAPIView):
    serializer_class = NotificationSerializer
    permission_classes = [permissions.IsAuthenticated]

    def update(self, request, *args, **kwargs):
        notif_id = kwargs.get('pk')
        notif = NotificationService.mark_as_read(request.user, notif_id)

        if not notif:
            return Response(
                {"detail": "Notification not found"},
                status=404
            )

        return Response(NotificationSerializer(notif).data)
