from rest_framework import generics, permissions, status
from rest_framework.response import Response
from rest_framework.views import APIView
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.db.models import Q, Prefetch, Count
from .models import Status, StatusView
from .serializers import (
    StatusSerializer,
    StatusDetailSerializer,
    StatusCreateSerializer,
    StatusViewerSerializer
)


class StatusCreateView(generics.CreateAPIView):
    """
    Create a new status
    POST /api/status/create/
    """
    serializer_class = StatusCreateSerializer
    permission_classes = [permissions.IsAuthenticated]

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

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        
        # Return full status details
        status_obj = Status.objects.get(id=serializer.instance.id)
        output_serializer = StatusSerializer(
            status_obj,
            context={'request': request}
        )
        
        return Response(
            {
                "message": "Status created successfully",
                "status": output_serializer.data
            },
            status=status.HTTP_201_CREATED
        )


class StatusFeedView(generics.ListAPIView):
    """
    Get status feed (own status + following users' status)
    Only shows non-expired status
    GET /api/status/feed/
    """
    serializer_class = StatusSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        
        # Get IDs of users that current user is following
        following_ids = user.following_relations.values_list("following_id", flat=True)
        
        # Get non-expired status from user and people they follow
        return Status.objects.filter(
            Q(user__id__in=list(following_ids)) | Q(user=user),
            expires_at__gt=timezone.now()  # Only non-expired
        ).select_related('user').prefetch_related('views').annotate(
            views_count=Count('views')
        ).order_by('-created_at')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        
        # Group by user for better frontend display
        grouped_status = {}
        for status_item in serializer.data:
            user_id = status_item['user_id']
            username = status_item['user_username']
            
            if user_id not in grouped_status:
                grouped_status[user_id] = {
                    'user_id': user_id,
                    'username': username,
                    'user_profile_image': status_item['user_profile_image'],
                    'statuses': []
                }
            
            grouped_status[user_id]['statuses'].append(status_item)
        
        return Response({
            'count': len(queryset),
            'results': list(grouped_status.values())
        })


class MyStatusListView(generics.ListAPIView):
    """
    Get current user's own status (non-expired only)
    GET /api/status/my-status/
    """
    serializer_class = StatusSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return Status.objects.filter(
            user=self.request.user,
            expires_at__gt=timezone.now()  # Only non-expired
        ).prefetch_related('views').annotate(
            views_count=Count('views')
        ).order_by('-created_at')


class StatusDetailView(generics.RetrieveAPIView):
    """
    Get a single status with viewer details
    GET /api/status/<id>/
    """
    serializer_class = StatusDetailSerializer
    permission_classes = [permissions.IsAuthenticated]
    queryset = Status.objects.all()
    lookup_field = 'id'
    lookup_url_kwarg = 'status_id'

    def get_queryset(self):
        # Only show non-expired status
        return Status.objects.filter(
            expires_at__gt=timezone.now()
        ).select_related('user').prefetch_related(
            'views',
            'views__viewer'
        ).annotate(views_count=Count('views'))

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        
        # Auto-mark as viewed if not the owner
        if instance.user != request.user:
            StatusView.objects.get_or_create(
                status=instance,
                viewer=request.user
            )
        
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class StatusDeleteView(generics.DestroyAPIView):
    """
    Delete a status (only by owner)
    DELETE /api/status/<id>/delete/
    """
    permission_classes = [permissions.IsAuthenticated]
    queryset = Status.objects.all()
    lookup_field = 'id'
    lookup_url_kwarg = 'status_id'

    def get_queryset(self):
        # Only allow users to delete their own status
        return Status.objects.filter(user=self.request.user)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response(
            {"message": "Status deleted successfully"},
            status=status.HTTP_200_OK
        )


class MarkStatusViewedView(APIView):
    """
    Mark a status as viewed
    POST /api/status/<id>/view/
    """
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, status_id):
        status_obj = get_object_or_404(
            Status,
            id=status_id,
            expires_at__gt=timezone.now()  # Only non-expired
        )
        
        # Don't track views from the owner
        if status_obj.user == request.user:
            return Response(
                {"message": "Cannot view your own status"},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # Create or get view record
        view, created = StatusView.objects.get_or_create(
            status=status_obj,
            viewer=request.user
        )
        
        return Response({
            "message": "Status marked as viewed" if created else "Already viewed",
            "viewed": True,
            "views_count": status_obj.views.count()
        })


class StatusViewersListView(generics.ListAPIView):
    """
    Get list of users who viewed a status
    GET /api/status/<id>/viewers/
    """
    serializer_class = StatusViewerSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        status_id = self.kwargs.get('status_id')
        
        # Only allow owner to see viewers
        status_obj = get_object_or_404(
            Status,
            id=status_id,
            user=self.request.user  # Must be owner
        )
        
        return StatusView.objects.filter(
            status=status_obj
        ).select_related('viewer').order_by('-viewed_at')

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        
        return Response({
            'count': len(queryset),
            'viewers': serializer.data
        })


class AllStatusListView(generics.ListAPIView):
    """
    Get all non-expired status from all users (for admin/testing)
    GET /api/status/all/
    """
    serializer_class = StatusSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        return Status.objects.filter(
            expires_at__gt=timezone.now()
        ).select_related('user').prefetch_related('views').annotate(
            views_count=Count('views')
        ).order_by('-created_at')