from django.db import models
from django.utils import timezone
from django.db.models import Q


class ChatRoomManager(models.Manager):

    def get_for_user(self, user_type, user_id):
        """Get all chat rooms for a user"""
        if user_type == "teacher":
            return self.filter(
                chatparticipantteacher__teacher_id=user_id,
                chatparticipantteacher__is_active=True,
                is_active=True,
            ).distinct()
        elif user_type == "parent":
            return self.filter(
                chatparticipantparent__parent_id=user_id,
                chatparticipantparent__is_active=True,
                is_active=True,
            ).distinct()
        elif user_type == "student":
            return self.filter(
                chatparticipantstudent__student_id=user_id,
                chatparticipantstudent__is_active=True,
                is_active=True,
            ).distinct()
        return self.none()

    def get_class_group(self, academic_class, academic_year=None):
        """Get or create class group chat"""
        if not academic_year:
            academic_year = academic_class.academic_year

        room, created = self.get_or_create(
            room_type="CLASS",
            academic_class=academic_class,
            academic_year=academic_year,
            defaults={
                "name": f"{academic_class} Class Group",
                "description": f"Official group for {academic_class}",
                "created_by_type": "system",
                "created_by_id": "system",
            },
        )

        if created:
            from .models import ChatParticipantStudent, ChatParticipantTeacher

            # Add students
            for enrollment in academic_class.enrollments.filter(is_active=True):
                ChatParticipantStudent.objects.get_or_create(
                    room=room, student=enrollment.student, defaults={"role": "MEMBER"}
                )

            # Add class teacher
            if academic_class.class_teacher:
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=academic_class.class_teacher,
                    defaults={"role": "ADMIN"},
                )

            # Add assistant teacher
            if academic_class.assistant_teacher:
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=academic_class.assistant_teacher,
                    defaults={"role": "MODERATOR"},
                )

            # Add subject teachers
            for subject_teacher in academic_class.subject_teachers.filter(
                is_active=True
            ):
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=subject_teacher.teacher,
                    defaults={"role": "MODERATOR"},
                )

        return room

    def get_subject_group(self, subject, academic_class, academic_year=None):
        """Get or create subject-specific group chat"""
        if not academic_year:
            academic_year = academic_class.academic_year

        room, created = self.get_or_create(
            room_type="SUBJECT",
            subject=subject,
            academic_class=academic_class,
            academic_year=academic_year,
            defaults={
                "name": f"{subject.name} - {academic_class}",
                "description": f"Group for {subject.name} in {academic_class}",
                "created_by_type": "system",
                "created_by_id": "system",
            },
        )

        if created:
            from .models import ChatParticipantStudent, ChatParticipantTeacher

            # Add students enrolled in this subject
            for enrollment in academic_class.enrollments.filter(is_active=True):
                if enrollment.selected_subjects.filter(subject=subject).exists():
                    ChatParticipantStudent.objects.get_or_create(
                        room=room,
                        student=enrollment.student,
                        defaults={"role": "MEMBER"},
                    )

            # Add subject teacher
            subject_teacher = academic_class.subject_teachers.filter(
                subject=subject, is_active=True
            ).first()

            if subject_teacher:
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=subject_teacher.teacher,
                    defaults={"role": "ADMIN"},
                )

        return room

    def get_parent_teacher_group(self, student, academic_year=None):
        """Get or create parent-teacher group for a student"""
        from academics.models import StudentEnrollment, AcademicYear

        if not academic_year:
            academic_year = AcademicYear.objects.filter(is_active=True).first()

        # Get student's current enrollment
        enrollment = StudentEnrollment.objects.filter(
            student=student, academic_class__academic_year=academic_year, is_active=True
        ).first()

        if not enrollment:
            return None

        room, created = self.get_or_create(
            room_type="PARENT_TEACHER",
            academic_class=enrollment.academic_class,
            defaults={
                "name": f"{student.full_name} - Parent-Teacher Group",
                "description": f"Parent-Teacher communication for {student.full_name}",
                "created_by_type": "system",
                "created_by_id": "system",
            },
        )

        if created:
            from .models import ChatParticipantParent, ChatParticipantTeacher

            # Add parents
            for student_parent in student.student_parents.filter(is_active=True):
                ChatParticipantParent.objects.get_or_create(
                    room=room, parent=student_parent.parent, defaults={"role": "MEMBER"}
                )

            # Add class teacher
            if enrollment.academic_class.class_teacher:
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=enrollment.academic_class.class_teacher,
                    defaults={"role": "ADMIN"},
                )

            # Add subject teachers
            for subject_teacher in enrollment.academic_class.subject_teachers.filter(
                is_active=True
            ):
                ChatParticipantTeacher.objects.get_or_create(
                    room=room,
                    teacher=subject_teacher.teacher,
                    defaults={"role": "MODERATOR"},
                )

        return room


class MessageManager(models.Manager):

    def get_unread_for_user(self, user_type, user_id):
        """Get unread messages for a user across all rooms"""
        from .models import MessageReadReceipt

        # Get all messages where user hasn't read
        read_messages = MessageReadReceipt.objects.filter(
            user_type=user_type, user_id=user_id
        ).values_list("message_id", flat=True)

        # Get messages from rooms where user is a participant
        if user_type == "teacher":
            return (
                self.exclude(id__in=read_messages)
                .exclude(sender_type=user_type, sender_id=user_id)
                .filter(
                    room__chatparticipantteacher__teacher_id=user_id,
                    room__chatparticipantteacher__is_active=True,
                )
            )
        elif user_type == "parent":
            return (
                self.exclude(id__in=read_messages)
                .exclude(sender_type=user_type, sender_id=user_id)
                .filter(
                    room__chatparticipantparent__parent_id=user_id,
                    room__chatparticipantparent__is_active=True,
                )
            )
        elif user_type == "student":
            return (
                self.exclude(id__in=read_messages)
                .exclude(sender_type=user_type, sender_id=user_id)
                .filter(
                    room__chatparticipantstudent__student_id=user_id,
                    room__chatparticipantstudent__is_active=True,
                )
            )
        return self.none()

    def get_for_room(self, room_id, user_type, user_id, limit=50, offset=0):
        """Get messages for a room with read status"""
        messages = self.filter(room_id=room_id, is_deleted=False).order_by(
            "-created_at"
        )[offset : offset + limit]

        # Annotate read status for this user
        for message in messages:
            message.user_has_read = message.read_receipts.filter(
                user_type=user_type, user_id=user_id
            ).exists()

        return messages
