from rest_framework import status, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from django.db.models import Q, Max, Count
from django.shortcuts import get_object_or_404
from accounts.models import User
from .models import Conversation, Message, BlockedUser


class ConversationListView(APIView):
    """List all conversations for the current user"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        user = request.user
        conversations = Conversation.objects.filter(
            Q(participant1=user) | Q(participant2=user)
        ).annotate(
            last_message_time=Max('messages__created_at'),
            unread_count=Count(
                'messages',
                filter=Q(messages__is_read=False) & ~Q(messages__sender=user)
            )
        ).order_by('-last_message_time')

        data = []
        for conv in conversations:
            other_user = conv.get_other_participant(user)
            last_message = conv.messages.order_by('-created_at').first()

            # Get other user's profile info
            profile_photo = None
            shop_name = None
            if other_user.profile_photo:
                profile_photo = request.build_absolute_uri(other_user.profile_photo.url)
            if hasattr(other_user, 'vendor_profile'):
                shop_name = other_user.vendor_profile.shop_name

            data.append({
                'id': conv.id,
                'other_user': {
                    'id': other_user.id,
                    'full_name': other_user.full_name,
                    'profile_photo': profile_photo,
                    'user_type': other_user.user_type,
                    'shop_name': shop_name,
                },
                'last_message': {
                    'content': last_message.content if last_message else None,
                    'message_type': last_message.message_type if last_message else None,
                    'sender_id': last_message.sender.id if last_message else None,
                    'created_at': last_message.created_at if last_message else None,
                } if last_message else None,
                'unread_count': conv.unread_count,
                'updated_at': conv.updated_at,
            })

        return Response({
            'success': True,
            'data': data
        }, status=status.HTTP_200_OK)


class ConversationDetailView(APIView):
    """Get or create a conversation with a specific user"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, user_id):
        user = request.user
        other_user = get_object_or_404(User, id=user_id)

        if user.id == other_user.id:
            return Response({
                'success': False,
                'message': 'Cannot create conversation with yourself'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Check if blocked
        if BlockedUser.is_blocked(user, other_user):
            return Response({
                'success': False,
                'message': 'Cannot start conversation - user is blocked'
            }, status=status.HTTP_403_FORBIDDEN)

        conversation = Conversation.get_or_create_conversation(user, other_user)

        # Get other user's profile info
        profile_photo = None
        shop_name = None
        if other_user.profile_photo:
            profile_photo = request.build_absolute_uri(other_user.profile_photo.url)
        if hasattr(other_user, 'vendor_profile'):
            shop_name = other_user.vendor_profile.shop_name

        return Response({
            'success': True,
            'data': {
                'id': conversation.id,
                'other_user': {
                    'id': other_user.id,
                    'full_name': other_user.full_name,
                    'profile_photo': profile_photo,
                    'user_type': other_user.user_type,
                    'shop_name': shop_name,
                },
                'is_blocked': BlockedUser.has_blocked(user, other_user),
                'blocked_by_other': BlockedUser.has_blocked(other_user, user),
            }
        }, status=status.HTTP_200_OK)


class MessageListView(APIView):
    """List messages in a conversation"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, conversation_id):
        user = request.user
        conversation = get_object_or_404(Conversation, id=conversation_id)

        if not conversation.is_participant(user):
            return Response({
                'success': False,
                'message': 'Not authorized to view this conversation'
            }, status=status.HTTP_403_FORBIDDEN)

        # Mark messages as read
        Message.objects.filter(
            conversation=conversation,
            is_read=False
        ).exclude(sender=user).update(is_read=True)

        # Get messages with pagination
        page = int(request.query_params.get('page', 1))
        limit = int(request.query_params.get('limit', 50))
        offset = (page - 1) * limit

        messages = conversation.messages.order_by('-created_at')[offset:offset + limit]
        total = conversation.messages.count()

        data = [{
            'id': msg.id,
            'message_type': msg.message_type,
            'content': msg.content,
            'image': msg.image.url if msg.image else None,
            'sender_id': msg.sender.id,
            'is_mine': msg.sender == user,
            'is_read': msg.is_read,
            'created_at': msg.created_at,
        } for msg in messages]

        # Reverse to show oldest first
        data.reverse()

        return Response({
            'success': True,
            'data': data,
            'pagination': {
                'total': total,
                'page': page,
                'limit': limit,
                'pages': (total + limit - 1) // limit
            }
        }, status=status.HTTP_200_OK)


class SendMessageView(APIView):
    """Send a message in a conversation"""
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]

    def post(self, request, conversation_id):
        user = request.user
        conversation = get_object_or_404(Conversation, id=conversation_id)

        if not conversation.is_participant(user):
            return Response({
                'success': False,
                'message': 'Not authorized to send messages in this conversation'
            }, status=status.HTTP_403_FORBIDDEN)

        other_user = conversation.get_other_participant(user)

        # Check if blocked
        if BlockedUser.is_blocked(user, other_user):
            return Response({
                'success': False,
                'message': 'Cannot send message - conversation is blocked'
            }, status=status.HTTP_403_FORBIDDEN)

        message_type = request.data.get('message_type', 'text')
        content = request.data.get('content', '')
        image = request.FILES.get('image')

        if message_type == 'text' and not content:
            return Response({
                'success': False,
                'message': 'Message content is required'
            }, status=status.HTTP_400_BAD_REQUEST)

        if message_type == 'image' and not image:
            return Response({
                'success': False,
                'message': 'Image file is required'
            }, status=status.HTTP_400_BAD_REQUEST)

        message = Message.objects.create(
            conversation=conversation,
            sender=user,
            message_type=message_type,
            content=content if message_type == 'text' else None,
            image=image if message_type == 'image' else None,
        )

        return Response({
            'success': True,
            'data': {
                'id': message.id,
                'message_type': message.message_type,
                'content': message.content,
                'image': message.image.url if message.image else None,
                'sender_id': message.sender.id,
                'is_mine': True,
                'is_read': message.is_read,
                'created_at': message.created_at,
            }
        }, status=status.HTTP_201_CREATED)


class StartConversationView(APIView):
    """Start a new conversation with a user"""
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser, JSONParser]

    def post(self, request):
        user = request.user
        other_user_id = request.data.get('user_id')

        if not other_user_id:
            return Response({
                'success': False,
                'message': 'user_id is required'
            }, status=status.HTTP_400_BAD_REQUEST)

        other_user = get_object_or_404(User, id=other_user_id)

        if user.id == other_user.id:
            return Response({
                'success': False,
                'message': 'Cannot create conversation with yourself'
            }, status=status.HTTP_400_BAD_REQUEST)

        # Check if blocked
        if BlockedUser.is_blocked(user, other_user):
            return Response({
                'success': False,
                'message': 'Cannot start conversation - user is blocked'
            }, status=status.HTTP_403_FORBIDDEN)

        conversation = Conversation.get_or_create_conversation(user, other_user)

        # Send initial message if provided
        message_type = request.data.get('message_type', 'text')
        content = request.data.get('content', '')
        image = request.FILES.get('image')

        message_data = None
        if content or image:
            message = Message.objects.create(
                conversation=conversation,
                sender=user,
                message_type=message_type,
                content=content if message_type == 'text' else None,
                image=image if message_type == 'image' else None,
            )
            message_data = {
                'id': message.id,
                'message_type': message.message_type,
                'content': message.content,
                'image': message.image.url if message.image else None,
                'sender_id': message.sender.id,
                'created_at': message.created_at,
            }

        # Get other user's profile info
        profile_photo = None
        shop_name = None
        if other_user.profile_photo:
            profile_photo = request.build_absolute_uri(other_user.profile_photo.url)
        if hasattr(other_user, 'vendor_profile'):
            shop_name = other_user.vendor_profile.shop_name

        return Response({
            'success': True,
            'data': {
                'conversation_id': conversation.id,
                'other_user': {
                    'id': other_user.id,
                    'full_name': other_user.full_name,
                    'profile_photo': profile_photo,
                    'user_type': other_user.user_type,
                    'shop_name': shop_name,
                },
                'message': message_data,
            }
        }, status=status.HTTP_201_CREATED)


class BlockUserView(APIView):
    """Block a user"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, user_id):
        user = request.user
        user_to_block = get_object_or_404(User, id=user_id)

        if user.id == user_to_block.id:
            return Response({
                'success': False,
                'message': 'Cannot block yourself'
            }, status=status.HTTP_400_BAD_REQUEST)

        if BlockedUser.has_blocked(user, user_to_block):
            return Response({
                'success': False,
                'message': 'User is already blocked'
            }, status=status.HTTP_400_BAD_REQUEST)

        BlockedUser.objects.create(blocker=user, blocked=user_to_block)

        return Response({
            'success': True,
            'message': 'User blocked successfully'
        }, status=status.HTTP_200_OK)


class UnblockUserView(APIView):
    """Unblock a user"""
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, user_id):
        user = request.user
        user_to_unblock = get_object_or_404(User, id=user_id)

        try:
            blocked = BlockedUser.objects.get(blocker=user, blocked=user_to_unblock)
            blocked.delete()
            return Response({
                'success': True,
                'message': 'User unblocked successfully'
            }, status=status.HTTP_200_OK)
        except BlockedUser.DoesNotExist:
            return Response({
                'success': False,
                'message': 'User is not blocked'
            }, status=status.HTTP_400_BAD_REQUEST)


class BlockedUsersListView(APIView):
    """List all blocked users"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        user = request.user
        blocked_users = BlockedUser.objects.filter(blocker=user).select_related('blocked')

        data = [{
            'id': blocked.blocked.id,
            'full_name': blocked.blocked.full_name,
            'profile_photo': blocked.blocked.profile_photo.url if blocked.blocked.profile_photo else None,
            'user_type': blocked.blocked.user_type,
            'blocked_at': blocked.created_at,
        } for blocked in blocked_users]

        return Response({
            'success': True,
            'data': data
        }, status=status.HTTP_200_OK)


class UnreadCountView(APIView):
    """Get total unread message count"""
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        user = request.user
        unread_count = Message.objects.filter(
            conversation__in=Conversation.objects.filter(
                Q(participant1=user) | Q(participant2=user)
            ),
            is_read=False
        ).exclude(sender=user).count()

        return Response({
            'success': True,
            'data': {
                'unread_count': unread_count
            }
        }, status=status.HTTP_200_OK)
