from rest_framework import serializers
from django.utils import timezone
from django.db.models import Q, Count
from .models import (
    ChatRoom,
    Message,
    ChatParticipantTeacher,
    ChatParticipantParent,
    ChatParticipantStudent,
    MessageReadReceipt,
    MessageDelivery,
    ChatMention,
    ChatPoll,
    ChatPollVote,
    ChatInvitation,
)
from people.models import Teacher, Parent, Student
from academics.models import AcademicClass, Subject
from django.conf import settings


class UserBasicInfoSerializer(serializers.Serializer):
    """Basic user information serializer"""

    id = serializers.CharField()
    type = serializers.CharField()
    name = serializers.CharField()
    email = serializers.EmailField(required=False, allow_null=True)
    profile_image = serializers.SerializerMethodField()
    role = serializers.CharField(required=False, allow_null=True)

    def get_profile_image(self, obj):
        """Get profile image URL"""
        if isinstance(obj, dict):
            return obj.get("profile_image")
        return None


class ChatParticipantTeacherSerializer(serializers.ModelSerializer):
    """Serializer for teacher participants"""

    user_data = serializers.SerializerMethodField()

    class Meta:
        model = ChatParticipantTeacher
        fields = [
            "id",
            "teacher",
            "role",
            "is_muted",
            "muted_until",
            "notification_enabled",
            "last_read_at",
            "pinned",
            "joined_at",
            "is_active",
            "user_data",
        ]
        read_only_fields = ["id", "joined_at", "last_active_at"]

    def get_user_data(self, obj):
        """Get teacher user data"""
        return {
            "id": str(obj.teacher.id),
            "type": "teacher",
            "name": obj.teacher.full_name,
            "email": obj.teacher.email,
            "profile_image": (
                obj.teacher.profile_image.url if obj.teacher.profile_image else None
            ),
            "role": obj.role,
        }


class ChatParticipantParentSerializer(serializers.ModelSerializer):
    """Serializer for parent participants"""

    user_data = serializers.SerializerMethodField()

    class Meta:
        model = ChatParticipantParent
        fields = [
            "id",
            "parent",
            "role",
            "is_muted",
            "muted_until",
            "notification_enabled",
            "last_read_at",
            "pinned",
            "joined_at",
            "is_active",
            "user_data",
        ]
        read_only_fields = ["id", "joined_at", "last_active_at"]

    def get_user_data(self, obj):
        """Get parent user data"""
        return {
            "id": str(obj.parent.id),
            "type": "parent",
            "name": obj.parent.full_name,
            "email": obj.parent.email,
            "profile_image": (
                obj.parent.profile_image.url if obj.parent.profile_image else None
            ),
            "role": obj.role,
        }


class ChatParticipantStudentSerializer(serializers.ModelSerializer):
    """Serializer for student participants"""

    user_data = serializers.SerializerMethodField()

    class Meta:
        model = ChatParticipantStudent
        fields = [
            "id",
            "student",
            "role",
            "is_muted",
            "muted_until",
            "notification_enabled",
            "last_read_at",
            "pinned",
            "joined_at",
            "is_active",
            "user_data",
        ]
        read_only_fields = ["id", "joined_at", "last_active_at"]

    def get_user_data(self, obj):
        """Get student user data"""
        return {
            "id": str(obj.student.id),
            "type": "student",
            "name": obj.student.full_name,
            "email": obj.student.personal_email,
            "profile_image": (
                obj.student.profile_image.url if obj.student.profile_image else None
            ),
            "role": obj.role,
            "roll_number": obj.student.roll_number,
            "student_id": obj.student.student_id,
        }


class MessageDeliverySerializer(serializers.ModelSerializer):
    """Serializer for delivery status with user info"""

    user_info = serializers.SerializerMethodField()

    class Meta:
        model = MessageDelivery
        fields = [
            "id",
            "user_type",
            "user_id",
            "status",
            "delivered_at",
            "read_at",
            "user_info",
        ]

    def get_user_info(self, obj):
        """Get user information for the delivery status"""
        if obj.user_type == "student":
            from people.models import Student

            try:
                student = Student.objects.get(id=obj.user_id)
                return {
                    "id": str(student.id),
                    "type": "student",
                    "name": student.full_name,
                    "profile_image": (
                        student.profile_image.url if student.profile_image else None
                    ),
                    "roll_number": student.roll_number,
                }
            except Student.DoesNotExist:
                return None
        elif obj.user_type == "teacher":
            from people.models import Teacher

            try:
                teacher = Teacher.objects.get(id=obj.user_id)
                return {
                    "id": str(teacher.id),
                    "type": "teacher",
                    "name": teacher.full_name,
                    "profile_image": (
                        teacher.profile_image.url if teacher.profile_image else None
                    ),
                }
            except Teacher.DoesNotExist:
                return None
        elif obj.user_type == "parent":
            from people.models import Parent

            try:
                parent = Parent.objects.get(id=obj.user_id)
                return {
                    "id": str(parent.id),
                    "type": "parent",
                    "name": parent.full_name,
                }
            except Parent.DoesNotExist:
                return None
        return None


class MessageReadReceiptSerializer(serializers.ModelSerializer):
    """Serializer for read receipts with user info"""

    user_info = serializers.SerializerMethodField()

    class Meta:
        model = MessageReadReceipt
        fields = ["id", "user_type", "user_id", "read_at", "user_info"]

    def get_user_info(self, obj):
        """Get user information for the receipt"""
        if obj.user_type == "student":
            from people.models import Student

            try:
                student = Student.objects.get(id=obj.user_id)
                return {
                    "id": str(student.id),
                    "type": "student",
                    "name": student.full_name,
                    "profile_image": (
                        student.profile_image.url if student.profile_image else None
                    ),
                    "roll_number": student.roll_number,
                }
            except Student.DoesNotExist:
                return None
        elif obj.user_type == "teacher":
            from people.models import Teacher

            try:
                teacher = Teacher.objects.get(id=obj.user_id)
                return {
                    "id": str(teacher.id),
                    "type": "teacher",
                    "name": teacher.full_name,
                    "profile_image": (
                        teacher.profile_image.url if teacher.profile_image else None
                    ),
                }
            except Teacher.DoesNotExist:
                return None
        elif obj.user_type == "parent":
            from people.models import Parent

            try:
                parent = Parent.objects.get(id=obj.user_id)
                return {
                    "id": str(parent.id),
                    "type": "parent",
                    "name": parent.full_name,
                }
            except Parent.DoesNotExist:
                return None
        return None

class MessageSerializer(serializers.ModelSerializer):
    """Serializer for messages with pagination optimization"""

    sender_name = serializers.SerializerMethodField()
    sender_details = serializers.SerializerMethodField()
    read_receipts = serializers.SerializerMethodField()
    delivery_status = serializers.SerializerMethodField()
    reply_to_data = serializers.SerializerMethodField()
    is_read_by_current_user = serializers.SerializerMethodField()
    file_url = serializers.SerializerMethodField()
    thumbnail_url = serializers.SerializerMethodField()

    class Meta:
        model = Message
        fields = [
            "id",
            "room",
            "sender_type",
            "sender_id",
            "sender_name",
            "sender_details",
            "message_type",
            "content",
            "content_encrypted",
            "is_encrypted",
            "file",
            "file_url",
            "file_name",
            "file_size",
            "file_type",
            "thumbnail",
            "thumbnail_url",
            "reply_to",
            "reply_to_data",
            "is_read",
            "read_at",
            "is_deleted",
            "deleted_at",
            "edited_at",
            "edit_history",
            "reactions",
            "metadata",
            "created_at",
            "updated_at",
            "read_receipts",
            "delivery_status",
            "is_read_by_current_user",
        ]
        read_only_fields = [
            "id",
            "created_at",
            "updated_at",
            "read_at",
            "deleted_at",
            "edited_at",
            "edit_history",
            "is_read",
        ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Cache for current user info to avoid repeated lookups
        self._current_user_type = None
        self._current_user_id = None
        self._current_user_read_status_cache = {}

    def _get_current_user_info(self):
        """Get current user info once and cache it"""
        if self._current_user_type is not None and self._current_user_id is not None:
            return self._current_user_type, self._current_user_id

        user_type = self.context.get("user_type")
        user_id = self.context.get("user_id")

        if not user_type or not user_id:
            request = self.context.get("request")
            if request and hasattr(request, "user_type") and hasattr(request, "user_id"):
                user_type = request.user_type
                user_id = str(request.user_id)

        self._current_user_type = user_type
        self._current_user_id = str(user_id) if user_id else None
        return self._current_user_type, self._current_user_id

    def get_sender_name(self, obj):
        """Get sender's display name"""
        return obj.get_sender_name()

    def get_sender_details(self, obj):
        """Get complete sender details"""
        return obj.get_sender_details()

    def get_reply_to_data(self, obj):
        """Get data for the message being replied to"""
        if obj.reply_to:
            return {
                "id": str(obj.reply_to.id),
                "sender_name": obj.reply_to.get_sender_name(),
                "content": (
                    obj.reply_to.content[:100] if obj.reply_to.content else "[Media]"
                ),
                "message_type": obj.reply_to.message_type,
            }
        return None

    def get_read_receipts(self, obj):
        """Get read receipts with pagination optimization"""
        # Only include read receipts for messages that need them
        # Limit to last 5 read receipts to reduce payload size
        read_receipts = obj.read_receipts.all().order_by('-read_at')[:5]
        return MessageReadReceiptSerializer(read_receipts, many=True).data

    def get_delivery_status(self, obj):
        """Get delivery status with pagination optimization"""
        # Only include delivery status for the current user's type
        user_type, user_id = self._get_current_user_info()
        
        if user_type and user_id:
            # Filter delivery status to only current user's status
            delivery = obj.delivery_status.filter(
                user_type=user_type, 
                user_id=user_id
            ).first()
            if delivery:
                return MessageDeliverySerializer([delivery], many=True).data
        
        # Fallback: return all but limited
        delivery_status = obj.delivery_status.all()[:10]
        return MessageDeliverySerializer(delivery_status, many=True).data

    def get_is_read_by_current_user(self, obj):
        """Check if current user has read this message - optimized for pagination"""
        user_type, user_id = self._get_current_user_info()

        if not user_type or not user_id:
            return False

        # Message sent by the current user - always considered read
        if obj.sender_type == user_type and str(obj.sender_id) == user_id:
            return True

        # Check cache first
        cache_key = f"{obj.id}_{user_type}_{user_id}"
        if cache_key in self._current_user_read_status_cache:
            return self._current_user_read_status_cache[cache_key]

        is_read = False

        # Check via delivery_status prefetched data (most efficient)
        if hasattr(obj, '_prefetched_objects_cache') and 'delivery_status' in obj._prefetched_objects_cache:
            for delivery in obj.delivery_status.all():
                if delivery.user_type == user_type and str(delivery.user_id) == user_id:
                    is_read = delivery.status == "READ"
                    break

        # Check via read_receipts prefetched data
        if not is_read and hasattr(obj, '_prefetched_objects_cache') and 'read_receipts' in obj._prefetched_objects_cache:
            for receipt in obj.read_receipts.all():
                if receipt.user_type == user_type and str(receipt.user_id) == user_id:
                    is_read = True
                    break

        # Cache the result
        self._current_user_read_status_cache[cache_key] = is_read
        return is_read

    def get_file_url(self, obj):
        """Get file URL if file exists"""
        if obj.file and hasattr(obj.file, "url"):
            request = self.context.get("request")
            if request:
                return request.build_absolute_uri(obj.file.url)
            return obj.file.url
        return None

    def get_thumbnail_url(self, obj):
        """Get thumbnail URL if exists"""
        if obj.thumbnail and hasattr(obj.thumbnail, "url"):
            request = self.context.get("request")
            if request:
                return request.build_absolute_uri(obj.thumbnail.url)
            return obj.thumbnail.url
        return None
class ChatRoomSerializer(serializers.ModelSerializer):
    """Serializer for chat rooms"""

    participants = serializers.SerializerMethodField()
    last_message = serializers.SerializerMethodField()
    unread_count = serializers.SerializerMethodField()
    participant_count = serializers.SerializerMethodField()
    academic_info = serializers.SerializerMethodField()
    created_by_info = serializers.SerializerMethodField()
    
    # NEW FIELDS FOR ADMIN/MODERATOR CHECKS
    is_admin = serializers.SerializerMethodField()
    is_moderator = serializers.SerializerMethodField()
    participant_role = serializers.SerializerMethodField()

    class Meta:
        model = ChatRoom
        fields = [
            "id",
            "room_type",
            "name",
            "description",
            "academic_class",
            "subject",
            "subject_group",
            "academic_year",
            "participants",
            "participant_count",
            "last_message",
            "unread_count",
            "academic_info",
            "is_encrypted",
            "allow_media",
            "allow_links",
            "slow_mode",
            "join_by_invite_only",
            "admins",
            "moderators",
            "created_by_info",
            "created_at",
            "updated_at",
            "last_message_at",
            "is_active",
            # NEW FIELDS
            "is_admin",
            "is_moderator",
            "participant_role",
        ]
        read_only_fields = ["id", "created_at", "updated_at", "last_message_at"]

    def get_participants(self, obj):
        """Get all participants in the room with their details"""
        request = self.context.get("request")
        participants = []

        # Get teacher participants
        for participant in obj.chatparticipantteacher_set.filter(is_active=True):
            participants.append(
                {
                    "id": str(participant.teacher.id),
                    "type": "teacher",
                    "name": participant.teacher.full_name,
                    "email": participant.teacher.email,
                    "profile_image": (
                        participant.teacher.profile_image.url
                        if participant.teacher.profile_image
                        else None
                    ),
                    "role": participant.role,
                    "is_admin": participant.role == "ADMIN",
                    "is_moderator": participant.role == "MODERATOR",
                    "is_muted": participant.is_muted,
                    "joined_at": participant.joined_at,
                }
            )

        # Get parent participants
        for participant in obj.chatparticipantparent_set.filter(is_active=True):
            participants.append(
                {
                    "id": str(participant.parent.id),
                    "type": "parent",
                    "name": participant.parent.full_name,
                    "email": participant.parent.email,
                    "profile_image": (
                        participant.parent.profile_image.url
                        if participant.parent.profile_image
                        else None
                    ),
                    "role": participant.role,
                    "is_admin": participant.role == "ADMIN",
                    "is_moderator": participant.role == "MODERATOR",
                    "is_muted": participant.is_muted,
                    "joined_at": participant.joined_at,
                }
            )

        # Get student participants
        for participant in obj.chatparticipantstudent_set.filter(is_active=True):
            participants.append(
                {
                    "id": str(participant.student.id),
                    "type": "student",
                    "name": participant.student.full_name,
                    "email": participant.student.personal_email,
                    "profile_image": (
                        participant.student.profile_image.url
                        if participant.student.profile_image
                        else None
                    ),
                    "role": participant.role,
                    "is_admin": participant.role == "ADMIN",
                    "is_moderator": participant.role == "MODERATOR",
                    "roll_number": participant.student.roll_number,
                    "joined_at": participant.joined_at,
                }
            )

        return participants

    def get_participant_count(self, obj):
        """Get total number of active participants"""
        count = obj.chatparticipantteacher_set.filter(is_active=True).count()
        count += obj.chatparticipantparent_set.filter(is_active=True).count()
        count += obj.chatparticipantstudent_set.filter(is_active=True).count()
        return count

    def get_last_message(self, obj):
        """Get the last message in the room"""
        last_message = (
            obj.messages.filter(is_deleted=False).order_by("-created_at").first()
        )
        if last_message:
            request = self.context.get("request")
            return MessageSerializer(last_message, context={"request": request}).data
        return None

    def get_unread_count(self, obj):
        """Get unread messages count for the current user"""
        request = self.context.get("request")
        user_type = self.context.get("user_type")
        user_id = self.context.get("user_id")
        
        # Try to get from context first, then from request
        if not user_type and request and hasattr(request, "user_type"):
            user_type = request.user_type
        if not user_id and request and hasattr(request, "user_id"):
            user_id = str(request.user_id)

        if user_type and user_id:
            # Get all messages in room
            messages = obj.messages.filter(is_deleted=False)

            # Get read receipts for this user
            read_messages = MessageReadReceipt.objects.filter(
                user_type=user_type, user_id=user_id, message__in=messages
            ).values_list("message_id", flat=True)

            # Count unread messages (excluding user's own messages)
            unread = (
                messages.exclude(id__in=read_messages)
                .exclude(sender_type=user_type, sender_id=user_id)
                .count()
            )

            return unread
        return 0

    def get_academic_info(self, obj):
        """Get academic information if this is an academic room"""
        info = {}

        if obj.academic_class:
            info["class"] = {
                "id": str(obj.academic_class.id),
                "name": str(obj.academic_class),
                "standard": (
                    obj.academic_class.standard.name
                    if obj.academic_class.standard
                    else None
                ),
                "section": (
                    obj.academic_class.section.name
                    if obj.academic_class.section
                    else None
                ),
                "academic_year": (
                    obj.academic_class.academic_year.name
                    if obj.academic_class.academic_year
                    else None
                ),
            }

        if obj.subject:
            info["subject"] = {
                "id": str(obj.subject.id),
                "name": obj.subject.name,
                "code": obj.subject.code,
                "category": obj.subject.category.name if obj.subject.category else None,
            }

        if obj.subject_group:
            info["subject_group"] = {
                "id": str(obj.subject_group.id),
                "name": obj.subject_group.name,
                "code": obj.subject_group.code,
            }

        if obj.academic_year:
            info["academic_year"] = {
                "id": str(obj.academic_year.id),
                "name": obj.academic_year.name,
                "start_date": obj.academic_year.start_date,
                "end_date": obj.academic_year.end_date,
            }

        return info if info else None

    def get_created_by_info(self, obj):
        """Get information about who created the room"""
        if obj.created_by_type and obj.created_by_id:
            if obj.created_by_type == "teacher":
                try:
                    teacher = Teacher.objects.get(id=obj.created_by_id)
                    return {
                        "type": "teacher",
                        "id": str(teacher.id),
                        "name": teacher.full_name,
                    }
                except Teacher.DoesNotExist:
                    pass
            elif obj.created_by_type == "parent":
                try:
                    parent = Parent.objects.get(id=obj.created_by_id)
                    return {
                        "type": "parent",
                        "id": str(parent.id),
                        "name": parent.full_name,
                    }
                except Parent.DoesNotExist:
                    pass
            elif obj.created_by_type == "student":
                try:
                    student = Student.objects.get(id=obj.created_by_id)
                    return {
                        "type": "student",
                        "id": str(student.id),
                        "name": student.full_name,
                    }
                except Student.DoesNotExist:
                    pass
        return None

    def get_is_admin(self, obj):
        """Check if current user is an admin of this room"""
        user_type = self.context.get("user_type")
        user_id = self.context.get("user_id")
        
        if not user_type or not user_id:
            request = self.context.get("request")
            if request:
                user_type = getattr(request, "user_type", None)
                user_id = getattr(request, "user_id", None)
        
        if user_type == "teacher" and user_id:
            participant = obj.chatparticipantteacher_set.filter(
                teacher_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "ADMIN"
            
        elif user_type == "parent" and user_id:
            participant = obj.chatparticipantparent_set.filter(
                parent_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "ADMIN"
            
        elif user_type == "student" and user_id:
            participant = obj.chatparticipantstudent_set.filter(
                student_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "ADMIN"
            
        return False

    def get_is_moderator(self, obj):
        """Check if current user is a moderator of this room"""
        user_type = self.context.get("user_type")
        user_id = self.context.get("user_id")
        
        if not user_type or not user_id:
            request = self.context.get("request")
            if request:
                user_type = getattr(request, "user_type", None)
                user_id = getattr(request, "user_id", None)
        
        if user_type == "teacher" and user_id:
            participant = obj.chatparticipantteacher_set.filter(
                teacher_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "MODERATOR"
            
        elif user_type == "parent" and user_id:
            participant = obj.chatparticipantparent_set.filter(
                parent_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "MODERATOR"
            
        elif user_type == "student" and user_id:
            participant = obj.chatparticipantstudent_set.filter(
                student_id=user_id, is_active=True
            ).first()
            return participant and participant.role == "MODERATOR"
            
        return False

    def get_participant_role(self, obj):
        """Get the role of current user in this room"""
        user_type = self.context.get("user_type")
        user_id = self.context.get("user_id")
        
        if not user_type or not user_id:
            request = self.context.get("request")
            if request:
                user_type = getattr(request, "user_type", None)
                user_id = getattr(request, "user_id", None)
        
        if user_type == "teacher" and user_id:
            participant = obj.chatparticipantteacher_set.filter(
                teacher_id=user_id, is_active=True
            ).first()
            return participant.role if participant else None
            
        elif user_type == "parent" and user_id:
            participant = obj.chatparticipantparent_set.filter(
                parent_id=user_id, is_active=True
            ).first()
            return participant.role if participant else None
            
        elif user_type == "student" and user_id:
            participant = obj.chatparticipantstudent_set.filter(
                student_id=user_id, is_active=True
            ).first()
            return participant.role if participant else None
            
        return None
    
class ChatRoomDetailSerializer(ChatRoomSerializer):
    """Detailed serializer for chat rooms with additional info"""

    messages = serializers.SerializerMethodField()

    class Meta(ChatRoomSerializer.Meta):
        fields = ChatRoomSerializer.Meta.fields + ["messages"]

    def get_messages(self, obj):
        """Get recent messages for the room"""
        request = self.context.get("request")
        limit = int(self.context.get("limit", 50))

        messages = obj.messages.filter(is_deleted=False).order_by("-created_at")[:limit]
        return MessageSerializer(messages, many=True, context={"request": request}).data


class ChatPollVoteSerializer(serializers.ModelSerializer):
    """Serializer for poll votes"""

    user_info = serializers.SerializerMethodField()

    class Meta:
        model = ChatPollVote
        fields = [
            "id",
            "poll",
            "user_type",
            "user_id",
            "option_index",
            "voted_at",
            "user_info",
        ]
        read_only_fields = ["id", "voted_at"]

    def get_user_info(self, obj):
        """Get user info for vote"""
        if obj.user_type == "teacher":
            try:
                teacher = Teacher.objects.get(id=obj.user_id)
                return {"id": obj.user_id, "type": "teacher", "name": teacher.full_name}
            except Teacher.DoesNotExist:
                return None
        elif obj.user_type == "parent":
            try:
                parent = Parent.objects.get(id=obj.user_id)
                return {"id": obj.user_id, "type": "parent", "name": parent.full_name}
            except Parent.DoesNotExist:
                return None
        elif obj.user_type == "student":
            try:
                student = Student.objects.get(id=obj.user_id)
                return {
                    "id": obj.user_id,
                    "type": "student",
                    "name": student.full_name,
                    "roll_number": student.roll_number,
                }
            except Student.DoesNotExist:
                return None
        return None


class ChatPollSerializer(serializers.ModelSerializer):
    """Serializer for polls in chat"""

    results = serializers.SerializerMethodField()
    user_vote = serializers.SerializerMethodField()
    votes = ChatPollVoteSerializer(many=True, read_only=True)

    class Meta:
        model = ChatPoll
        fields = [
            "id",
            "message",
            "question",
            "options",
            "is_multiple",
            "is_anonymous",
            "ends_at",
            "created_by_type",
            "created_by_id",
            "total_votes",
            "results",
            "user_vote",
            "votes",
            "created_at",
        ]
        read_only_fields = ["id", "created_at", "total_votes"]

    def get_results(self, obj):
        """Get poll results with percentages"""
        results = obj.get_results()
        total = obj.total_votes

        formatted_results = {}
        for option_index, vote_count in results.items():
            percentage = (vote_count / total * 100) if total > 0 else 0
            formatted_results[option_index] = {
                "votes": vote_count,
                "percentage": round(percentage, 1),
            }

        return formatted_results

    def get_user_vote(self, obj):
        """Get current user's vote"""
        request = self.context.get("request")
        if request and hasattr(request, "user_type") and hasattr(request, "user_id"):
            vote = obj.votes.filter(
                user_type=request.user_type, user_id=str(request.user_id)
            ).first()

            if vote:
                return {"option_index": vote.option_index, "voted_at": vote.voted_at}
        return None


class ChatInvitationSerializer(serializers.ModelSerializer):
    """Serializer for chat invitations"""

    room_info = serializers.SerializerMethodField()
    invited_by_info = serializers.SerializerMethodField()
    invitee_info = serializers.SerializerMethodField()

    class Meta:
        model = ChatInvitation
        fields = [
            "id",
            "room",
            "room_info",
            "user_type",
            "user_id",
            "invitee_info",
            "invited_by_type",
            "invited_by_id",
            "invited_by_info",
            "status",
            "expires_at",
            "created_at",
            "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]

    def get_room_info(self, obj):
        """Get basic room information"""
        return {
            "id": str(obj.room.id),
            "name": obj.room.name,
            "room_type": obj.room.room_type,
        }

    def get_invited_by_info(self, obj):
        """Get information about who sent the invitation"""
        if obj.invited_by_type == "teacher":
            try:
                teacher = Teacher.objects.get(id=obj.invited_by_id)
                return {
                    "type": "teacher",
                    "id": str(teacher.id),
                    "name": teacher.full_name,
                }
            except Teacher.DoesNotExist:
                pass
        elif obj.invited_by_type == "parent":
            try:
                parent = Parent.objects.get(id=obj.invited_by_id)
                return {
                    "type": "parent",
                    "id": str(parent.id),
                    "name": parent.full_name,
                }
            except Parent.DoesNotExist:
                pass
        return None

    def get_invitee_info(self, obj):
        """Get information about the invited user"""
        if obj.user_type == "teacher":
            try:
                teacher = Teacher.objects.get(id=obj.user_id)
                return {
                    "type": "teacher",
                    "id": str(teacher.id),
                    "name": teacher.full_name,
                    "email": teacher.email,
                }
            except Teacher.DoesNotExist:
                pass
        elif obj.user_type == "parent":
            try:
                parent = Parent.objects.get(id=obj.user_id)
                return {
                    "type": "parent",
                    "id": str(parent.id),
                    "name": parent.full_name,
                    "email": parent.email,
                }
            except Parent.DoesNotExist:
                pass
        elif obj.user_type == "student":
            try:
                student = Student.objects.get(id=obj.user_id)
                return {
                    "type": "student",
                    "id": str(student.id),
                    "name": student.full_name,
                    "email": student.personal_email,
                    "roll_number": student.roll_number,
                }
            except Student.DoesNotExist:
                pass
        return None


class ChatMentionSerializer(serializers.ModelSerializer):
    """Serializer for message mentions"""

    user_info = serializers.SerializerMethodField()
    message_preview = serializers.SerializerMethodField()

    class Meta:
        model = ChatMention
        fields = [
            "id",
            "message",
            "message_preview",
            "user_type",
            "user_id",
            "user_info",
            "is_notified",
            "notified_at",
            "created_at",
        ]
        read_only_fields = ["id", "created_at"]

    def get_user_info(self, obj):
        """Get user information for mentioned user"""
        if obj.user_type == "teacher":
            try:
                teacher = Teacher.objects.get(id=obj.user_id)
                return {
                    "type": "teacher",
                    "id": str(teacher.id),
                    "name": teacher.full_name,
                }
            except Teacher.DoesNotExist:
                pass
        elif obj.user_type == "parent":
            try:
                parent = Parent.objects.get(id=obj.user_id)
                return {
                    "type": "parent",
                    "id": str(parent.id),
                    "name": parent.full_name,
                }
            except Parent.DoesNotExist:
                pass
        elif obj.user_type == "student":
            try:
                student = Student.objects.get(id=obj.user_id)
                return {
                    "type": "student",
                    "id": str(student.id),
                    "name": student.full_name,
                    "roll_number": student.roll_number,
                }
            except Student.DoesNotExist:
                pass
        return None

    def get_message_preview(self, obj):
        """Get preview of the message"""
        if obj.message:
            return {
                "id": str(obj.message.id),
                "content": (
                    obj.message.content[:100] if obj.message.content else "[Media]"
                ),
                "sender_name": obj.message.get_sender_name(),
                "created_at": obj.message.created_at,
            }
        return None


class ChatParticipantSettingsSerializer(serializers.Serializer):
    """Serializer for updating participant settings"""

    is_muted = serializers.BooleanField(required=False)
    muted_until = serializers.DateTimeField(required=False, allow_null=True)
    notification_enabled = serializers.BooleanField(required=False)
    pinned = serializers.BooleanField(required=False)


class CreateChatRoomSerializer(serializers.Serializer):
    """Serializer for creating a new chat room"""

    room_type = serializers.ChoiceField(choices=ChatRoom.ROOM_TYPES)
    name = serializers.CharField(required=False, allow_blank=True)
    description = serializers.CharField(required=False, allow_blank=True)
    participants = serializers.ListField(child=serializers.DictField(), required=True)
    is_encrypted = serializers.BooleanField(default=True)
    allow_media = serializers.BooleanField(default=True)
    allow_links = serializers.BooleanField(default=True)
    slow_mode = serializers.IntegerField(default=0, min_value=0)
    join_by_invite_only = serializers.BooleanField(default=False)

    def validate_participants(self, value):
        """Validate participants list"""
        if not value:
            raise serializers.ValidationError("At least one participant is required")

        for participant in value:
            if "type" not in participant or "id" not in participant:
                raise serializers.ValidationError(
                    "Each participant must have 'type' and 'id'"
                )

            if participant["type"] not in ["teacher", "parent", "student"]:
                raise serializers.ValidationError(
                    f"Invalid participant type: {participant['type']}"
                )

        return value


class SendMessageSerializer(serializers.Serializer):
    """Serializer for sending a new message"""

    content = serializers.CharField(required=True)
    message_type = serializers.ChoiceField(
        choices=Message.MESSAGE_TYPES, default="TEXT"
    )
    reply_to_id = serializers.UUIDField(required=False, allow_null=True)

    def validate_content(self, value):
        """Validate message content"""
        if not value or not value.strip():
            raise serializers.ValidationError("Message content cannot be empty")

        if len(value) > 5000:
            raise serializers.ValidationError("Message too long (max 5000 characters)")

        return value


class CreatePollSerializer(serializers.Serializer):
    """Serializer for creating a poll"""

    question = serializers.CharField(max_length=500)
    options = serializers.ListField(
        child=serializers.CharField(max_length=200), min_length=2, max_length=10
    )
    is_multiple = serializers.BooleanField(default=False)
    is_anonymous = serializers.BooleanField(default=False)
    ends_at = serializers.DateTimeField()

    def validate_ends_at(self, value):
        """Validate poll end time"""
        if value <= timezone.now():
            raise serializers.ValidationError("End time must be in the future")
        return value


class VotePollSerializer(serializers.Serializer):
    """Serializer for voting on a poll"""

    option_index = serializers.IntegerField(min_value=0)

    def validate_option_index(self, value):
        """Validate option index"""
        # This will be validated against the poll's options in the view
        return value


class MessageReactionSerializer(serializers.Serializer):
    """Serializer for adding/removing message reactions"""

    reaction = serializers.CharField(max_length=50)
    action = serializers.ChoiceField(choices=["add", "remove"], default="add")


class ChatSearchSerializer(serializers.Serializer):
    """Serializer for searching messages"""

    query = serializers.CharField(required=True, min_length=2)
    room_id = serializers.UUIDField(required=False, allow_null=True)
    from_date = serializers.DateField(required=False, allow_null=True)
    to_date = serializers.DateField(required=False, allow_null=True)
    sender_type = serializers.ChoiceField(
        choices=["teacher", "parent", "student"], required=False, allow_null=True
    )
    limit = serializers.IntegerField(default=50, min_value=1, max_value=100)
    offset = serializers.IntegerField(default=0, min_value=0)


class ChatExportSerializer(serializers.Serializer):
    """Serializer for exporting chat history"""

    room_id = serializers.UUIDField(required=True)
    format = serializers.ChoiceField(choices=["json", "csv", "pdf"], default="json")
    from_date = serializers.DateField(required=False, allow_null=True)
    to_date = serializers.DateField(required=False, allow_null=True)
    include_metadata = serializers.BooleanField(default=True)
