from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.contrib.auth.models import User
from django.db.models import Q
from .models import Message, Room
from .serializers import ChatUserSerializer, MessageSerializer
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from rest_framework.parsers import MultiPartParser, FormParser

# 1. لیست مخاطبین (همکاران)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_contacts(request):
    # دریافت تمام کاربران فعال به جز خود درخواست‌دهنده
    users = User.objects.filter(is_active=True).exclude(id=request.user.id)

    #  context را پاس میده 
    serializer = ChatUserSerializer(users, many=True, context={'request': request})
    return Response(serializer.data)

# 2. تاریخچه پیام‌های یک اتاق خاص
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_room_history(request, room_name):
    # چک امنیتی ساده برای چت‌های خصوصی
    if room_name.startswith('private_'):
        try:
            # فرمت private_1_2 است. باید چک کنیم کاربر جاری یکی از این آیدی‌ها باشد
            ids = room_name.replace('private_', '').split('_')
            user_id = str(request.user.id)
            if user_id not in ids:
                return Response({'detail': 'شما عضو این گفتگو نیستید.'}, status=403)
        except:
            return Response({'detail': 'نام اتاق نامعتبر است.'}, status=400)

    try:
        # دریافت اتاق و پیام‌ها
        room = Room.objects.get(name=room_name)
        # پیام‌ها را مرتب شده برمی‌گردانیم
        messages = room.messages.all().order_by('timestamp')
        serializer = MessageSerializer(messages, many=True, context={'request': request})
        return Response(serializer.data)
    except Room.DoesNotExist:
        # اگر اتاق هنوز ساخته نشده (پیامی رد و بدل نشده)، لیست خالی برگردان
        return Response([])


# 3. پیام های خوانده نشده
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_total_unread_count(request):
    user = request.user

    count = Message.objects.filter(
        # شرط 1: اتاق‌هایی که مربوط به من است (شامل آیدی من در نام اتاق)
        Q(room__name__contains=f"_{user.id}") | Q(room__name__endswith=f"_{user.id}"),
        # شرط 2: فرستنده من نیستم
        ~Q(sender=user),
        # شرط 3: خوانده نشده
        is_read=False
    ).count()
    
    return Response({'total_unread': count})


# 4. آپلود تصویر
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def upload_chat_image(request):
    """
    این ویو عکس را می‌گیرد، ذخیره می‌کند و سپس از طریق Channel Layer
    به گروه سوکت مربوطه خبر می‌دهد.
    """
    room_name = request.data.get('room_name')
    content = request.data.get('content', '') # متن هم می‌تواند همراه عکس باشد
    image = request.FILES.get('image')

    if not room_name or not image:
        return Response({'detail': 'اطلاعات ناقص است'}, status=400)

    try:
        # 1. پیدا کردن یا ساختن اتاق
        # نکته: لاجیک پیدا کردن اتاق باید مثل Consumer باشد
        # اگر private است و هنوز ساخته نشده، اینجا ساخته می‌شود
        room, created = Room.objects.get_or_create(name=room_name)
        if created:
            room.room_type = 'public' if room_name == 'general' else 'private'
            room.save()

        # 2. ذخیره پیام در دیتابیس
        msg = Message.objects.create(
            room=room,
            sender=request.user,
            content=content,
            image=image
        )

        # 3. آماده‌سازی دیتا برای ارسال به سوکت
        # سریالایزر را با context ریکوئست صدا می‌زنیم تا آدرس عکس کامل باشد
        serializer = MessageSerializer(msg, context={'request': request})
        message_data = serializer.data

        # 4. ارسال خبر به گروه سوکت (Broadcasting)
        channel_layer = get_channel_layer()
        room_group_name = f'chat_{room_name}'
        
        async_to_sync(channel_layer.group_send)(
            room_group_name,
            {
                'type': 'chat_message', # همان هندلری که در Consumer داریم
                'message': message_data['content'],
                'user_id': message_data['user_id'],
                'username': message_data['sender_name'],
                'user_avatar': message_data['sender_avatar'],
                'image': message_data['image'], # ارسال لینک عکس
                'is_read': False
            }
        )
        
        # اگر چت خصوصی است، نوتیفیکیشن هم بفرستیم
        if 'private_' in room_name:
             ids = room_name.replace('private_', '').split('_')
             current_user_id = str(request.user.id)
             receiver_id = ids[0] if str(ids[0]) != current_user_id else ids[1]
             
             async_to_sync(channel_layer.group_send)(
                f"notify_user_{receiver_id}",
                {
                    'type': 'send_notification',
                    'message_type': 'new_message',
                    'sender_id': request.user.id,
                    'sender_name': request.user.get_full_name() or request.user.username
                }
            )

        return Response(serializer.data, status=201)

    except Exception as e:
        print(e)
        return Response({'detail': str(e)}, status=500)