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 UserMessageFilter
from apps.calls.serializers import MessageSerializer, MessageDetailSerializer
from apps.calls.services import MessageService
from apps.calls.pagination import UnreadReadPagination


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

    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = UserMessageFilter
    search_fields = ['customer_name', 'recipient__username']

    ordering_fields = ['created_at', 'is_read']
    ordering = ['-created_at']

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

    def get_queryset(self):
        queryset = MessageService.list_messages(self.request.user)

        self._unfiltered_qs = queryset
        return queryset

    @property
    def unfiltered_qs(self):
        return self._unfiltered_qs
    
class MessageDetailView(generics.RetrieveAPIView):
    serializer_class = MessageDetailSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return MessageService.list_messages(self.request.user)

class MarkMessageReadView(generics.UpdateAPIView):
    serializer_class = MessageDetailSerializer
    permission_classes = [permissions.IsAuthenticated]

    def update(self, request, *args, **kwargs):
        msg_id = kwargs.get('pk')
        msg = MessageService.mark_as_read(request.user, msg_id)

        if not msg:
            return Response(
                {'detail': 'Message not found or does not belong to you'},
                status=404
            )
        
        return Response(MessageDetailSerializer(msg).data)
