# =====================================================
# TEACHER MARKS MANAGEMENT VIEWS
# =====================================================

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from django.db import transaction
from django.db.models import Q, Avg, Count, Sum, F, Prefetch
from django.utils import timezone
from datetime import date
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from people.models import Teacher
from academics.models import (
    AcademicClass, SubjectTeacher, StudentEnrollment, 
    AcademicYear, Subject, StudentSubject
)
from exam.models import (
    Exam, ExamSubject, StudentMarks, ExamResult,
    StudentExamRegistration
)
from .teacher_marks_serializers import (
    TeacherSubjectClassListSerializer,
    TeacherSubjectStudentsSerializer,
    StudentMarksCreateSerializer,
    StudentMarksUpdateSerializer,
    SubjectMarksSummarySerializer,
    StudentMarksDetailSerializer,
    BulkMarksEntrySerializer,
    MarksSubmissionSerializer
)

import logging
logger = logging.getLogger(__name__)


class TeacherSubjectsStandardsView(APIView):
    """
    GET /teacher/marks/subjects-standards/
    
    Get all subjects and standards that the teacher teaches.
    This is the first step - shows what the teacher can select.
    
    Returns grouped by standard with subjects under each standard.
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            # Get current academic year
            academic_year = AcademicYear.objects.filter(is_active=True).first()
            if not academic_year:
                return Response(
                    {"success": False, "message": "No active academic year found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get all subjects teacher teaches with class info
            subject_teachers = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class__academic_year=academic_year,
                is_active=True
            ).select_related(
                'subject',
                'academic_class__standard',
                'academic_class__section'
            ).order_by('academic_class__standard__order', 'subject__name')
            
            # Group by standard
            standards_data = {}
            
            for st in subject_teachers:
                standard = st.academic_class.standard
                standard_key = standard.id
                
                if standard_key not in standards_data:
                    standards_data[standard_key] = {
                        'standard_id': standard.id,
                        'standard_name': standard.name,
                        'standard_code': standard.code,
                        'standard_type': standard.standard_type,
                        'classes': {},
                        'total_subjects': 0
                    }
                
                class_key = st.academic_class.id
                if class_key not in standards_data[standard_key]['classes']:
                    standards_data[standard_key]['classes'][class_key] = {
                        'class_id': st.academic_class.id,
                        'class_name': str(st.academic_class),
                        'section': st.academic_class.section.code,
                        'total_students': StudentEnrollment.objects.filter(
                            academic_class=st.academic_class,
                            is_active=True
                        ).count(),
                        'subjects': []
                    }
                
                # Add subject if not already added for this class
                subject_exists = any(
                    s['subject_id'] == st.subject.id 
                    for s in standards_data[standard_key]['classes'][class_key]['subjects']
                )
                
                if not subject_exists:
                    standards_data[standard_key]['classes'][class_key]['subjects'].append({
                        'subject_id': st.subject.id,
                        'subject_name': st.subject.name,
                        'subject_code': st.subject.code,
                        'subject_type': st.subject.subject_type
                    })
                    standards_data[standard_key]['total_subjects'] += 1
            
            # Convert to list format
            result = []
            for std_data in standards_data.values():
                # Convert classes dict to list
                std_data['classes'] = list(std_data['classes'].values())
                result.append(std_data)
            
            # Calculate total counts
            total_standards = len(result)
            total_classes = sum(len(std['classes']) for std in result)
            total_subjects = sum(std['total_subjects'] for std in result)
            
            return Response({
                "success": True,
                "data": {
                    "standards": result,
                    "summary": {
                        "total_standards": total_standards,
                        "total_classes": total_classes,
                        "total_subjects": total_subjects
                    }
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherSubjectsStandardsView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class TeacherClassExamsView(APIView):
    """
    GET /teacher/marks/class-exams/
    
    Get all exams for a specific class and subject with pagination.
    Shows upcoming, ongoing, and completed exams separately.
    
    Query Parameters:
    - class_id (required)
    - subject_id (required)
    - exam_status (optional) - 'upcoming', 'ongoing', 'completed', 'results_published', 'all'
    - page (optional, default=1)
    - page_size (optional, default=10)
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            # Get required parameters
            class_id = request.query_params.get('class_id')
            subject_id = request.query_params.get('subject_id')
            exam_status_filter = request.query_params.get('exam_status', 'all')
            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 10))
            
            if not class_id or not subject_id:
                return Response(
                    {"success": False, "message": "class_id and subject_id are required"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Verify teacher teaches this subject in this class
            subject_teacher = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class_id=class_id,
                subject_id=subject_id,
                is_active=True
            ).select_related('subject', 'academic_class__standard', 'academic_class__section').first()
            
            if not subject_teacher:
                return Response(
                    {"success": False, "message": "You are not authorized to access this subject in this class"},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            # Get academic class
            academic_class = subject_teacher.academic_class
            subject = subject_teacher.subject
            
            # Get all exams for this class
            exams = Exam.objects.filter(
                academic_class=academic_class,
                is_active=True
            ).select_related('exam_type').order_by('-start_date')
            
            today = timezone.now().date()
            
            # Categorize exams
            upcoming_exams = []
            ongoing_exams = []
            completed_exams = []
            results_published_exams = []
            
            for exam in exams:
                # Get exam subject details
                exam_subject = ExamSubject.objects.filter(
                    exam=exam,
                    subject=subject,
                    is_active=True
                ).first()
                
                if not exam_subject:
                    continue
                
                # Get marks statistics
                total_students = StudentEnrollment.objects.filter(
                    academic_class=academic_class, is_active=True
                ).count()
                
                marks_entered = StudentMarks.objects.filter(
                    exam_subject=exam_subject
                ).count()
                
                pending_count = total_students - marks_entered
                completion_percentage = round((marks_entered / total_students * 100), 2) if total_students > 0 else 0

                # Categorize by this subject's own exam date, not the overall
                # exam's date range or its rarely-updated status field.
                if exam.status == 'results_published':
                    display_status = 'results_published'
                elif exam_subject.exam_date is None or exam_subject.exam_date > today:
                    display_status = 'upcoming'
                elif exam_subject.exam_date == today:
                    display_status = 'ongoing'
                else:
                    display_status = 'completed'

                exam_data = {
                    'exam_id': exam.id,
                    'exam_name': exam.name,
                    'exam_code': exam.code,
                    'exam_type': exam.exam_type.name,
                    'exam_type_id': exam.exam_type.id,
                    # The bucket this exam was sorted into below ('upcoming' /
                    # 'ongoing' / 'completed' / 'results_published') — NOT the
                    # raw Exam.status field, which the admin rarely updates and
                    # stays 'scheduled' indefinitely.
                    'status': display_status,
                    'exam_status': exam.status,
                    'start_date': exam.start_date,
                    'end_date': exam.end_date,
                    'duration_days': exam.duration_days,
                    'max_marks': exam_subject.max_marks,
                    'passing_marks': exam_subject.passing_marks,
                    'exam_date': exam_subject.exam_date,
                    'start_time': exam_subject.start_time,
                    'duration_minutes': exam_subject.duration_minutes,
                    'room_number': exam_subject.room_number,
                    'total_students': total_students,
                    'marks_entered': marks_entered,
                    'pending_count': pending_count,
                    'completion_percentage': completion_percentage,
                    'can_enter_marks': self._can_enter_marks(exam, exam_subject),
                    'is_results_published': exam.status == 'results_published'
                }

                if display_status == 'results_published':
                    results_published_exams.append(exam_data)
                elif display_status == 'upcoming':
                    upcoming_exams.append(exam_data)
                elif display_status == 'ongoing':
                    ongoing_exams.append(exam_data)
                else:
                    completed_exams.append(exam_data)
            
            # Prepare response based on filter
            all_exams = []
            if exam_status_filter == 'upcoming':
                all_exams = upcoming_exams
                title = "Upcoming Exams"
            elif exam_status_filter == 'ongoing':
                all_exams = ongoing_exams
                title = "Ongoing Exams"
            elif exam_status_filter == 'completed':
                all_exams = completed_exams
                title = "Completed Exams"
            elif exam_status_filter == 'results_published':
                all_exams = results_published_exams
                title = "Results Published Exams"
            else:
                all_exams = upcoming_exams + ongoing_exams + completed_exams + results_published_exams
                title = "All Exams"
            
            # Apply pagination
            paginator = Paginator(all_exams, page_size)
            try:
                paginated_exams = paginator.page(page)
            except PageNotAnInteger:
                paginated_exams = paginator.page(1)
            except EmptyPage:
                paginated_exams = paginator.page(paginator.num_pages)
            
            return Response({
                "success": True,
                "data": {
                    "class_info": {
                        "class_id": academic_class.id,
                        "class_name": str(academic_class),
                        "standard": academic_class.standard.name,
                        "section": academic_class.section.code,
                        "total_students": StudentEnrollment.objects.filter(
                            academic_class=academic_class, is_active=True
                        ).count()
                    },
                    "subject_info": {
                        "subject_id": subject.id,
                        "subject_name": subject.name,
                        "subject_code": subject.code,
                        "subject_type": subject.subject_type
                    },
                    "exams": {
                        "title": title,
                        "current_filter": exam_status_filter,
                        "data": list(paginated_exams),
                        "pagination": {
                            "current_page": paginated_exams.number,
                            "total_pages": paginator.num_pages,
                            "total_items": paginator.count,
                            "page_size": page_size,
                            "has_next": paginated_exams.has_next(),
                            "has_previous": paginated_exams.has_previous()
                        }
                    },
                    "counts": {
                        "upcoming": len(upcoming_exams),
                        "ongoing": len(ongoing_exams),
                        "completed": len(completed_exams),
                        "results_published": len(results_published_exams),
                        "total": len(upcoming_exams) + len(ongoing_exams) + len(completed_exams) + len(results_published_exams)
                    }
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherClassExamsView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    def _can_enter_marks(self, exam, exam_subject):
        """Marks open once this subject's own exam date has passed."""
        if exam.status in ('cancelled', 'results_published'):
            return False
        if exam_subject.exam_date is None:
            return False
        return exam_subject.exam_date <= timezone.now().date()


class TeacherSubjectsWithClassesView(APIView):
    """
    GET /teacher/marks/subjects/
    
    Get all subjects that the teacher teaches in the current academic year,
    along with the classes for each subject.
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            # Get current academic year
            academic_year = AcademicYear.objects.filter(is_active=True).first()
            if not academic_year:
                return Response(
                    {"success": False, "message": "No active academic year found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get all subjects teacher teaches
            subject_teachers = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class__academic_year=academic_year,
                is_active=True
            ).select_related(
                'subject',
                'academic_class__standard',
                'academic_class__section'
            ).order_by('academic_class__standard__order', 'subject__name')
            
            # Group by class and subject
            data = []
            for st in subject_teachers:
                # Get exams for this class
                exams = Exam.objects.filter(
                    academic_class=st.academic_class,
                    is_active=True,
                    status__in=['scheduled', 'ongoing', 'completed', 'results_published']
                ).select_related('exam_type').order_by('-start_date')
                
                exam_info = []
                for exam in exams:
                    exam_subject = ExamSubject.objects.filter(
                        exam=exam, subject=st.subject, is_active=True
                    ).first()
                    if not exam_subject:
                        continue

                    # Check if marks can be entered for this exam
                    can_enter_marks = self._can_enter_marks(exam, exam_subject)

                    exam_info.append({
                        'exam_id': exam.id,
                        'exam_name': exam.name,
                        'exam_code': exam.code,
                        'exam_type': exam.exam_type.name,
                        'exam_status': exam.status,
                        'start_date': exam.start_date,
                        'end_date': exam.end_date,
                        'exam_date': exam_subject.exam_date,
                        'can_enter_marks': can_enter_marks,
                        'marks_entered_count': StudentMarks.objects.filter(
                            exam_subject__exam=exam,
                            exam_subject__subject=st.subject,
                            student_enrollment__academic_class=st.academic_class
                        ).count()
                    })
                
                data.append({
                    'subject_id': st.subject.id,
                    'subject_name': st.subject.name,
                    'subject_code': st.subject.code,
                    'class_id': st.academic_class.id,
                    'class_name': str(st.academic_class),
                    'standard': st.academic_class.standard.name,
                    'section': st.academic_class.section.code,
                    'total_students': StudentEnrollment.objects.filter(
                        academic_class=st.academic_class,
                        is_active=True
                    ).count(),
                    'exams': exam_info
                })
            
            return Response({
                "success": True,
                "data": data,
                "total_subjects": len(data)
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherSubjectsWithClassesView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    def _can_enter_marks(self, exam, exam_subject):
        """Marks open once this subject's own exam date has passed."""
        if exam.status in ('cancelled', 'results_published'):
            return False
        if exam_subject.exam_date is None:
            return False
        return exam_subject.exam_date <= timezone.now().date()

class TeacherClassStudentsForMarksView(APIView):
    """
    GET /teacher/marks/class-students/
    
    Get all students in a specific class for a specific subject and exam.
    Used when teacher wants to enter marks for a subject.
    
    Query Parameters:
    - class_id (required)
    - subject_id (required)
    - exam_id (required)
    - page (optional, default=1)
    - page_size (optional, default=20)
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            # Get required parameters
            class_id = request.query_params.get('class_id')
            subject_id = request.query_params.get('subject_id')
            exam_id = request.query_params.get('exam_id')
            page = int(request.query_params.get('page', 1))
            page_size = int(request.query_params.get('page_size', 20))
            
            if not class_id or not subject_id or not exam_id:
                return Response(
                    {"success": False, "message": "class_id, subject_id, and exam_id are required"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Verify teacher teaches this subject in this class
            subject_teacher = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class_id=class_id,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not subject_teacher:
                return Response(
                    {"success": False, "message": "You are not authorized to teach this subject in this class"},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            # Get academic class
            academic_class = AcademicClass.objects.filter(
                id=class_id, is_active=True
            ).select_related('standard', 'section').first()
            
            if not academic_class:
                return Response(
                    {"success": False, "message": "Class not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get exam
            exam = Exam.objects.filter(
                id=exam_id,
                academic_class=academic_class,
                is_active=True
            ).first()
            
            if not exam:
                return Response(
                    {"success": False, "message": "Exam not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get exam subject
            exam_subject = ExamSubject.objects.filter(
                exam=exam,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not exam_subject:
                return Response(
                    {"success": False, "message": "Exam subject not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get all students in this class
            enrollments = StudentEnrollment.objects.filter(
                academic_class=academic_class,
                is_active=True
            ).select_related('student').order_by('roll_number')
            
            # Filter students who take this subject (for higher secondary)
            if academic_class.standard.standard_type == 'higher_secondary':
                enrollments = enrollments.filter(
                    Q(selected_subjects__subject_id=subject_id) |
                    Q(subject_groups__subject_group__subjects__id=subject_id)
                ).distinct()
            
            # Get existing marks
            marks_map = {}
            existing_marks = StudentMarks.objects.filter(
                exam_subject=exam_subject,
                student_enrollment__in=enrollments
            ).select_related('student_enrollment')
            
            for mark in existing_marks:
                marks_map[mark.student_enrollment_id] = mark
            
            # Build students data with pagination
            all_students_data = []
            for enrollment in enrollments:
                existing_mark = marks_map.get(enrollment.id)
                
                student_data = {
                    'enrollment_id': enrollment.id,
                    'student_id': enrollment.student.id,
                    'student_name': enrollment.student.full_name or 
                                   f"{enrollment.student.first_name} {enrollment.student.last_name}".strip(),
                    'profile_image': enrollment.student.profile_image.url if enrollment.student.profile_image else None,
                    'roll_number': enrollment.roll_number,
                    'admission_number': enrollment.student.admission_number,
                    'marks_id': existing_mark.id if existing_mark else None,
                    'obtained_marks': float(existing_mark.obtained_marks) if existing_mark and existing_mark.obtained_marks is not None else None,
                    'is_absent': existing_mark.is_absent if existing_mark else False,
                    'is_passed': existing_mark.is_passed if existing_mark else None,
                    'percentage': float(existing_mark.percentage) if existing_mark and existing_mark.percentage is not None else None,
                    'grade': existing_mark.grade if existing_mark else None,
                    'remarks': existing_mark.remarks if existing_mark else '',
                    'has_marks': existing_mark is not None
                }
                all_students_data.append(student_data)
            
            # Apply pagination
            paginator = Paginator(all_students_data, page_size)
            try:
                paginated_students = paginator.page(page)
            except PageNotAnInteger:
                paginated_students = paginator.page(1)
            except EmptyPage:
                paginated_students = paginator.page(paginator.num_pages)
            
            # Calculate statistics
            total_students = len(all_students_data)
            marks_entered = len([s for s in all_students_data if s['has_marks']])
            marks_pending = total_students - marks_entered
            average_marks = None
            pass_percentage = None
            
            if marks_entered > 0:
                marks_list = [s['obtained_marks'] for s in all_students_data if s['obtained_marks'] is not None]
                if marks_list:
                    average_marks = round(sum(marks_list) / len(marks_list), 2)
                    passed = len([s for s in all_students_data if s['is_passed'] is True])
                    pass_percentage = round((passed / marks_entered) * 100, 2) if marks_entered > 0 else 0
            
            return Response({
                "success": True,
                "data": {
                    "class_info": {
                        "class_id": academic_class.id,
                        "class_name": str(academic_class),
                        "standard": academic_class.standard.name,
                        "section": academic_class.section.code,
                        "total_students": total_students
                    },
                    "subject_info": {
                        "subject_id": subject_id,
                        "subject_name": subject_teacher.subject.name,
                        "subject_code": subject_teacher.subject.code
                    },
                    "exam_info": {
                        'exam_id': exam.id,
                        'exam_name': exam.name,
                        'exam_code': exam.code,
                        'exam_status': exam.status,
                        'max_marks': exam_subject.max_marks,
                        'passing_marks': exam_subject.passing_marks,
                        'exam_date': exam_subject.exam_date,
                        'start_time': exam_subject.start_time,
                        'duration_minutes': exam_subject.duration_minutes,
                        'room_number': exam_subject.room_number,
                        # Marks can only be entered once the subject's own exam date has
                        # passed (and only once the admin has actually assigned one).
                        'can_edit_marks': (
                            exam.status not in ('results_published', 'cancelled')
                            and exam_subject.exam_date is not None
                            and exam_subject.exam_date <= date.today()
                        )
                    },
                    "students": {
                        "data": list(paginated_students),
                        "pagination": {
                            "current_page": paginated_students.number,
                            "total_pages": paginator.num_pages,
                            "total_items": paginator.count,
                            "page_size": page_size,
                            "has_next": paginated_students.has_next(),
                            "has_previous": paginated_students.has_previous()
                        }
                    },
                    "statistics": {
                        "total_students": total_students,
                        "marks_entered": marks_entered,
                        "marks_pending": marks_pending,
                        "completion_percentage": round((marks_entered / total_students * 100), 2) if total_students > 0 else 0,
                        "average_marks": average_marks,
                        "pass_percentage": pass_percentage
                    }
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherClassStudentsForMarksView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
            
class TeacherEnterStudentMarksView(APIView):
    """
    POST /teacher/marks/enter/
    
    Enter or update marks for a single student.
    
    Request Body:
    {
        "enrollment_id": 123,
        "subject_id": 456,
        "exam_id": 789,
        "obtained_marks": 85.5,
        "is_absent": false,
        "remarks": "Good performance"
    }
    """
    
    permission_classes = [IsAuthenticated]
    
    def post(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            serializer = StudentMarksCreateSerializer(data=request.data)
            if not serializer.is_valid():
                return Response(
                    {"success": False, "errors": serializer.errors},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            data = serializer.validated_data
            enrollment_id = data['enrollment_id']
            subject_id = data['subject_id']
            exam_id = data['exam_id']
            obtained_marks = data.get('obtained_marks')
            is_absent = data.get('is_absent', False)
            remarks = data.get('remarks', '')
            
            # Verify teacher teaches this subject
            enrollment = StudentEnrollment.objects.filter(
                id=enrollment_id, is_active=True
            ).select_related('academic_class', 'student').first()
            
            if not enrollment:
                return Response(
                    {"success": False, "message": "Enrollment not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Verify teacher teaches this subject in this class
            subject_teacher = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class=enrollment.academic_class,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not subject_teacher:
                return Response(
                    {"success": False, "message": "You are not authorized to enter marks for this subject in this class"},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            # Get exam subject
            exam_subject = ExamSubject.objects.filter(
                exam_id=exam_id,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not exam_subject:
                return Response(
                    {"success": False, "message": "Exam subject not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Verify exam belongs to the correct class
            if exam_subject.exam.academic_class_id != enrollment.academic_class_id:
                return Response(
                    {"success": False, "message": "Exam does not belong to this class"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Check if marks can be entered
            exam = exam_subject.exam
            if exam.status == 'results_published':
                return Response(
                    {"success": False, "message": "Results already published. Cannot enter marks."},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Validate marks
            if obtained_marks is not None and not is_absent:
                if obtained_marks < 0:
                    return Response(
                        {"success": False, "message": "Marks cannot be negative"},
                        status=status.HTTP_400_BAD_REQUEST
                    )
                if obtained_marks > exam_subject.max_marks:
                    return Response(
                        {"success": False, "message": f"Marks cannot exceed {exam_subject.max_marks}"},
                        status=status.HTTP_400_BAD_REQUEST
                    )
            
            # Create or update marks
            with transaction.atomic():
                # REMOVED: 'grade' and 'percentage' - they are @properties, not database fields
                marks, created = StudentMarks.objects.update_or_create(
                    student_enrollment=enrollment,
                    exam_subject=exam_subject,
                    defaults={
                        'obtained_marks': None if is_absent else obtained_marks,
                        'is_absent': is_absent,
                        'remarks': remarks,
                        'entered_by': teacher,
                    }
                )
                
                # Update exam result after marks entry
                self._update_exam_result(enrollment, exam)
                
                logger.info(
                    f"Marks {'created' if created else 'updated'} for student {enrollment.student.id} "
                    f"in exam {exam.id} subject {subject_id} by teacher {teacher.id}"
                )
            
            return Response({
                "success": True,
                "message": f"Marks {'entered' if created else 'updated'} successfully",
                "data": StudentMarksDetailSerializer(marks).data
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherEnterStudentMarksView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    def _calculate_grade(self, marks, max_marks):
        """Calculate grade based on percentage"""
        if marks is None:
            return ''
        
        percentage = (marks / max_marks) * 100
        
        if percentage >= 90:
            return 'A+'
        elif percentage >= 80:
            return 'A'
        elif percentage >= 70:
            return 'B+'
        elif percentage >= 60:
            return 'B'
        elif percentage >= 50:
            return 'C'
        elif percentage >= 40:
            return 'D'
        else:
            return 'F'
    
    def _update_exam_result(self, enrollment, exam):
        """Update the consolidated exam result after marks changes"""
        exam_subjects = ExamSubject.objects.filter(exam=exam, is_active=True)
        
        # Get all marks for this student in this exam
        marks = StudentMarks.objects.filter(
            student_enrollment=enrollment,
            exam_subject__in=exam_subjects
        )
        
        if not marks.exists():
            return
        
        total_obtained = 0
        total_max = 0
        total_passed = 0
        total_subjects = 0
        
        for mark in marks:
            if not mark.is_absent and mark.obtained_marks is not None:
                total_obtained += mark.obtained_marks
                total_max += mark.exam_subject.max_marks
                if mark.is_passed:
                    total_passed += 1
                total_subjects += 1
            elif not mark.is_absent:
                total_max += mark.exam_subject.max_marks
                total_subjects += 1
        
        percentage = (total_obtained / total_max * 100) if total_max > 0 else 0
        
        # Determine result status
        passing_marks_percentage = exam.exam_type.passing_marks / exam.exam_type.max_marks * 100
        if total_subjects == 0:
            result_status = 'absent'
        elif percentage >= passing_marks_percentage:
            result_status = 'pass'
        else:
            result_status = 'fail'
        
        # Update or create exam result
        ExamResult.objects.update_or_create(
            student_enrollment=enrollment,
            exam=exam,
            defaults={
                'total_marks': total_obtained,
                'total_max_marks': total_max,
                'percentage': percentage,
                'overall_grade': self._calculate_grade(total_obtained, total_max) if total_max > 0 else '',
                'result_status': result_status
            }
        )


class TeacherBulkMarksEntryView(APIView):
    """
    POST /teacher/marks/bulk-entry/
    
    Enter marks for multiple students at once.
    
    Request Body:
    {
        "exam_id": 789,
        "subject_id": 456,
        "marks_data": [
            {"enrollment_id": 123, "obtained_marks": 85, "is_absent": false, "remarks": "Good"},
            {"enrollment_id": 124, "obtained_marks": 0, "is_absent": true, "remarks": "Sick"}
        ]
    }
    """
    
    permission_classes = [IsAuthenticated]
    
    def post(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            serializer = BulkMarksEntrySerializer(data=request.data)
            if not serializer.is_valid():
                return Response(
                    {"success": False, "errors": serializer.errors},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            data = serializer.validated_data
            exam_id = data['exam_id']
            subject_id = data['subject_id']
            marks_data = data['marks_data']
            
            # Get exam subject
            exam_subject = ExamSubject.objects.filter(
                exam_id=exam_id,
                subject_id=subject_id,
                is_active=True
            ).select_related('exam').first()
            
            if not exam_subject:
                return Response(
                    {"success": False, "message": "Exam subject not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            exam = exam_subject.exam

            # Check if marks can be entered
            if exam.status == 'results_published':
                return Response(
                    {"success": False, "message": "Results already published. Cannot enter marks."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            if exam.status == 'cancelled':
                return Response(
                    {"success": False, "message": "This exam has been cancelled. Cannot enter marks."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            if exam_subject.exam_date is None:
                return Response(
                    {"success": False, "message": "This subject's exam date has not been scheduled yet. Ask an admin to assign it from the Exam Timetable."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            if exam_subject.exam_date > date.today():
                return Response(
                    {"success": False, "message": f"Marks entry opens on {exam_subject.exam_date.strftime('%d %b %Y')}, once the exam has taken place."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Get all enrollments
            enrollment_ids = [item['enrollment_id'] for item in marks_data]
            enrollments = {
                e.id: e for e in StudentEnrollment.objects.filter(
                    id__in=enrollment_ids, is_active=True
                ).select_related('academic_class', 'student')
            }
            
            # Verify teacher teaches this subject in these classes
            class_ids = set(e.academic_class_id for e in enrollments.values())
            
            for class_id in class_ids:
                subject_teacher = SubjectTeacher.objects.filter(
                    teacher=teacher,
                    academic_class_id=class_id,
                    subject_id=subject_id,
                    is_active=True
                ).first()
                
                if not subject_teacher:
                    return Response(
                        {"success": False, "message": f"You are not authorized for class {class_id}"},
                        status=status.HTTP_403_FORBIDDEN
                    )
            
            # Process bulk marks entry
            results = []
            errors = []
            
            with transaction.atomic():
                for item in marks_data:
                    enrollment_id = item['enrollment_id']
                    obtained_marks = item.get('obtained_marks')
                    is_absent = item.get('is_absent', False)
                    remarks = item.get('remarks', '')
                    
                    enrollment = enrollments.get(enrollment_id)
                    if not enrollment:
                        errors.append({
                            'enrollment_id': enrollment_id,
                            'error': 'Enrollment not found'
                        })
                        continue
                    
                    # Validate marks
                    if obtained_marks is not None and not is_absent:
                        if obtained_marks < 0:
                            errors.append({
                                'enrollment_id': enrollment_id,
                                'error': 'Marks cannot be negative'
                            })
                            continue
                        if obtained_marks > exam_subject.max_marks:
                            errors.append({
                                'enrollment_id': enrollment_id,
                                'error': f'Marks cannot exceed {exam_subject.max_marks}'
                            })
                            continue
                    
                    # Create or update marks
                    # REMOVED: 'grade' and 'percentage' - they are @properties, not database fields
                    marks, created = StudentMarks.objects.update_or_create(
                        student_enrollment=enrollment,
                        exam_subject=exam_subject,
                        defaults={
                            'obtained_marks': None if is_absent else obtained_marks,
                            'is_absent': is_absent,
                            'remarks': remarks,
                            'entered_by': teacher,
                        }
                    )
                    
                    results.append({
                        'enrollment_id': enrollment_id,
                        'student_name': enrollment.student.full_name,
                        'action': 'created' if created else 'updated',
                        'marks_id': marks.id
                    })
                    
                    # Update exam result
                    self._update_exam_result(enrollment, exam)
                
                logger.info(
                    f"Bulk marks entry completed for exam {exam_id} subject {subject_id} "
                    f"by teacher {teacher.id}. Success: {len(results)}, Errors: {len(errors)}"
                )
            
            return Response({
                "success": True,
                "message": f"Processed {len(results)} students successfully. {len(errors)} errors.",
                "data": {
                    "exam_info": {
                        "exam_id": exam.id,
                        "exam_name": exam.name,
                        "subject_id": subject_id,
                        "subject_name": exam_subject.subject.name,
                        "max_marks": exam_subject.max_marks
                    },
                    "successful": results,
                    "errors": errors if errors else None,
                    "total_success": len(results),
                    "total_errors": len(errors)
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherBulkMarksEntryView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    def _calculate_grade(self, marks, max_marks):
        """Calculate grade based on percentage"""
        if marks is None:
            return ''
        
        percentage = (marks / max_marks) * 100
        
        if percentage >= 90:
            return 'A+'
        elif percentage >= 80:
            return 'A'
        elif percentage >= 70:
            return 'B+'
        elif percentage >= 60:
            return 'B'
        elif percentage >= 50:
            return 'C'
        elif percentage >= 40:
            return 'D'
        else:
            return 'F'
    
    def _update_exam_result(self, enrollment, exam):
        """Update the consolidated exam result after marks changes"""
        exam_subjects = ExamSubject.objects.filter(exam=exam, is_active=True)
        
        marks = StudentMarks.objects.filter(
            student_enrollment=enrollment,
            exam_subject__in=exam_subjects
        )
        
        if not marks.exists():
            return
        
        total_obtained = 0
        total_max = 0
        total_passed = 0
        total_subjects = 0
        
        for mark in marks:
            if not mark.is_absent and mark.obtained_marks is not None:
                total_obtained += mark.obtained_marks
                total_max += mark.exam_subject.max_marks
                if mark.is_passed:
                    total_passed += 1
                total_subjects += 1
            elif not mark.is_absent:
                total_max += mark.exam_subject.max_marks
                total_subjects += 1
        
        percentage = (total_obtained / total_max * 100) if total_max > 0 else 0
        
        passing_marks_percentage = exam.exam_type.passing_marks / exam.exam_type.max_marks * 100
        if total_subjects == 0:
            result_status = 'absent'
        elif percentage >= passing_marks_percentage:
            result_status = 'pass'
        else:
            result_status = 'fail'
        
        ExamResult.objects.update_or_create(
            student_enrollment=enrollment,
            exam=exam,
            defaults={
                'total_marks': total_obtained,
                'total_max_marks': total_max,
                'percentage': percentage,
                'overall_grade': self._calculate_grade(total_obtained, total_max) if total_max > 0 else '',
                'result_status': result_status
            }
        ) 
        
class TeacherSubjectMarksSummaryView(APIView):
    """
    GET /teacher/marks/subject-summary/
    
    Get marks summary for a specific subject in a specific exam.
    
    Query Parameters:
    - exam_id (required)
    - subject_id (required)
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            exam_id = request.query_params.get('exam_id')
            subject_id = request.query_params.get('subject_id')
            
            if not exam_id or not subject_id:
                return Response(
                    {"success": False, "message": "exam_id and subject_id are required"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Get exam subject
            exam_subject = ExamSubject.objects.filter(
                exam_id=exam_id,
                subject_id=subject_id,
                is_active=True
            ).select_related('exam', 'subject', 'exam__academic_class').first()
            
            if not exam_subject:
                return Response(
                    {"success": False, "message": "Exam subject not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            exam = exam_subject.exam
            academic_class = exam.academic_class
            
            # Verify teacher teaches this subject in this class
            subject_teacher = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class=academic_class,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not subject_teacher:
                return Response(
                    {"success": False, "message": "You are not authorized to view marks for this subject"},
                    status=status.HTTP_403_FORBIDDEN
                )
            
            # Get all marks for this exam subject
            marks = StudentMarks.objects.filter(
                exam_subject=exam_subject
            ).select_related('student_enrollment__student')
            
            # Fetch all marks into a list to calculate properties in Python
            marks_list = list(marks)
            
            # Calculate statistics using Python (since is_passed and percentage are @properties)
            passed_marks = []
            failed_marks = []
            absent_marks = []
            entered_marks = []
            
            for mark in marks_list:
                if mark.is_absent:
                    absent_marks.append(mark)
                elif mark.obtained_marks is not None:
                    entered_marks.append(mark)
                    if mark.is_passed:
                        passed_marks.append(mark)
                    else:
                        failed_marks.append(mark)
            
            # Get marks values for calculations
            marks_values = [float(m.obtained_marks) for m in entered_marks if m.obtained_marks is not None]
            
            absent_count = len(absent_marks)
            total_students = StudentEnrollment.objects.filter(
                academic_class=academic_class, is_active=True
            ).count()
            marks_entered_count = len(entered_marks)
            
            if marks_values:
                statistics = {
                    'total_students': total_students,
                    'marks_entered': marks_entered_count,
                    'absent_count': absent_count,
                    'pending_count': total_students - marks_entered_count - absent_count,
                    'highest_marks': max(marks_values) if marks_values else None,
                    'lowest_marks': min(marks_values) if marks_values else None,
                    'average_marks': round(sum(marks_values) / len(marks_values), 2) if marks_values else None,
                    'pass_count': len(passed_marks),
                    'fail_count': len(failed_marks),
                    'pass_percentage': round((len(passed_marks) / marks_entered_count * 100), 2) if marks_entered_count > 0 else 0
                }
            else:
                statistics = {
                    'total_students': total_students,
                    'marks_entered': 0,
                    'absent_count': 0,
                    'pending_count': total_students,
                    'highest_marks': None,
                    'lowest_marks': None,
                    'average_marks': None,
                    'pass_count': 0,
                    'fail_count': 0,
                    'pass_percentage': 0
                }
            
            # Get mark distribution (filter in Python since we already have the marks)
            distribution = {
                '90-100': len([m for m in entered_marks if m.obtained_marks >= 90 and m.obtained_marks <= 100]),
                '80-89': len([m for m in entered_marks if m.obtained_marks >= 80 and m.obtained_marks <= 89]),
                '70-79': len([m for m in entered_marks if m.obtained_marks >= 70 and m.obtained_marks <= 79]),
                '60-69': len([m for m in entered_marks if m.obtained_marks >= 60 and m.obtained_marks <= 69]),
                '50-59': len([m for m in entered_marks if m.obtained_marks >= 50 and m.obtained_marks <= 59]),
                '40-49': len([m for m in entered_marks if m.obtained_marks >= 40 and m.obtained_marks <= 49]),
                'below-40': len([m for m in entered_marks if m.obtained_marks < 40])
            }
            
            return Response({
                "success": True,
                "data": {
                    "exam_info": {
                        "exam_id": exam.id,
                        "exam_name": exam.name,
                        "exam_code": exam.code,
                        "exam_status": exam.status,
                        # Marks can only be entered once the subject's own exam date has
                        # passed (and only once the admin has actually assigned one).
                        "can_edit_marks": (
                            exam.status not in ('results_published', 'cancelled')
                            and exam_subject.exam_date is not None
                            and exam_subject.exam_date <= date.today()
                        )
                    },
                    "subject_info": {
                        "subject_id": subject_id,
                        "subject_name": exam_subject.subject.name,
                        "subject_code": exam_subject.subject.code,
                        "max_marks": exam_subject.max_marks,
                        "passing_marks": exam_subject.passing_marks,
                        "exam_date": exam_subject.exam_date,
                        "start_time": exam_subject.start_time,
                        "duration_minutes": exam_subject.duration_minutes,
                        "room_number": exam_subject.room_number
                    },
                    "class_info": {
                        "class_id": academic_class.id,
                        "class_name": str(academic_class)
                    },
                    "statistics": statistics,
                    "distribution": distribution
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherSubjectMarksSummaryView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class TeacherSubmitMarksView(APIView):
    """
    POST /teacher/marks/submit/
    
    Submit/finalize marks for a specific exam subject.
    This indicates that teacher has completed entering marks.
    
    Request Body:
    {
        "exam_id": 789,
        "subject_id": 456,
        "submit": true
    }
    """
    
    permission_classes = [IsAuthenticated]
    
    def post(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            serializer = MarksSubmissionSerializer(data=request.data)
            if not serializer.is_valid():
                return Response(
                    {"success": False, "errors": serializer.errors},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            data = serializer.validated_data
            exam_id = data['exam_id']
            subject_id = data['subject_id']
            submit = data.get('submit', True)
            
            # Get exam subject
            exam_subject = ExamSubject.objects.filter(
                exam_id=exam_id,
                subject_id=subject_id,
                is_active=True
            ).select_related('exam', 'exam__academic_class').first()
            
            if not exam_subject:
                return Response(
                    {"success": False, "message": "Exam subject not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            exam = exam_subject.exam
            academic_class = exam.academic_class
            
            # Verify teacher teaches this subject
            subject_teacher = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class=academic_class,
                subject_id=subject_id,
                is_active=True
            ).first()
            
            if not subject_teacher:
                return Response(
                    {"success": False, "message": "You are not authorized to submit marks for this subject"},
                    status=status.HTTP_403_FORBIDDEN
                )

            if exam_subject.exam_date is None or exam_subject.exam_date > date.today():
                return Response(
                    {"success": False, "message": "Marks cannot be submitted before the exam date."},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # Check if all students have marks
            total_students = StudentEnrollment.objects.filter(
                academic_class=academic_class, is_active=True
            ).count()
            
            marks_entered = StudentMarks.objects.filter(
                exam_subject=exam_subject
            ).count()
            
            if marks_entered < total_students:
                pending = total_students - marks_entered
                return Response(
                    {
                        "success": False,
                        "message": f"Cannot submit marks. {pending} student(s) pending.",
                        "data": {
                            "total_students": total_students,
                            "marks_entered": marks_entered,
                            "pending_count": pending
                        }
                    },
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Here you can add a field to track submission status per exam subject
            # For now, just log and return success
            logger.info(
                f"Marks submitted for exam {exam_id} subject {subject_id} by teacher {teacher.id}"
            )
            
            return Response({
                "success": True,
                "message": f"Marks submitted successfully for {exam_subject.subject.name}",
                "data": {
                    "exam_id": exam_id,
                    "subject_id": subject_id,
                    "subject_name": exam_subject.subject.name,
                    "submitted_at": timezone.now(),
                    "marks_entered_count": marks_entered
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherSubmitMarksView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class TeacherPendingMarksView(APIView):
    """
    GET /teacher/marks/pending/
    
    Get all exams/subjects where marks are pending (not fully entered).
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            # Get current academic year
            academic_year = AcademicYear.objects.filter(is_active=True).first()
            if not academic_year:
                return Response(
                    {"success": False, "message": "No active academic year found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get all subjects teacher teaches
            subject_teachers = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class__academic_year=academic_year,
                is_active=True
            ).select_related(
                'subject',
                'academic_class__standard',
                'academic_class__section'
            )
            
            pending_items = []
            
            for st in subject_teachers:
                # Get exams for this class where marks can be entered
                exams = Exam.objects.filter(
                    academic_class=st.academic_class,
                    is_active=True,
                    status__in=['ongoing', 'completed']
                ).exclude(status='results_published')
                
                for exam in exams:
                    exam_subject = ExamSubject.objects.filter(
                        exam=exam,
                        subject=st.subject,
                        is_active=True
                    ).first()
                    
                    if exam_subject:
                        total_students = StudentEnrollment.objects.filter(
                            academic_class=st.academic_class, is_active=True
                        ).count()
                        
                        marks_entered = StudentMarks.objects.filter(
                            exam_subject=exam_subject
                        ).count()
                        
                        pending_count = total_students - marks_entered
                        
                        if pending_count > 0:
                            pending_items.append({
                                'exam_id': exam.id,
                                'exam_name': exam.name,
                                'exam_code': exam.code,
                                'exam_status': exam.status,
                                'start_date': exam.start_date,
                                'end_date': exam.end_date,
                                'subject_id': st.subject.id,
                                'subject_name': st.subject.name,
                                'subject_code': st.subject.code,
                                'class_id': st.academic_class.id,
                                'class_name': str(st.academic_class),
                                'total_students': total_students,
                                'marks_entered': marks_entered,
                                'pending_count': pending_count,
                                'completion_percentage': round((marks_entered / total_students * 100), 2) if total_students > 0 else 0
                            })
            
            # Sort by exam date (closest first)
            pending_items.sort(key=lambda x: x['start_date'])
            
            return Response({
                "success": True,
                "data": {
                    "pending_items": pending_items,
                    "total_pending": len(pending_items),
                    "total_students_pending": sum(item['pending_count'] for item in pending_items)
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherPendingMarksView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class TeacherExamSubjectsForMarksView(APIView):
    """
    GET /teacher/marks/exam-subjects/
    
    Get all exam subjects for a specific exam that the teacher teaches.
    
    Query Parameters:
    - exam_id (required)
    """
    
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        try:
            teacher = Teacher.objects.get(external_user_id=request.user.id)
            
            exam_id = request.query_params.get('exam_id')
            if not exam_id:
                return Response(
                    {"success": False, "message": "exam_id is required"},
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            exam = Exam.objects.filter(
                id=exam_id, is_active=True
            ).select_related('academic_class').first()
            
            if not exam:
                return Response(
                    {"success": False, "message": "Exam not found"},
                    status=status.HTTP_404_NOT_FOUND
                )
            
            # Get subjects teacher teaches in this class
            teacher_subjects = SubjectTeacher.objects.filter(
                teacher=teacher,
                academic_class=exam.academic_class,
                is_active=True
            ).values_list('subject_id', flat=True)
            
            # Get exam subjects for this exam that the teacher teaches
            exam_subjects = ExamSubject.objects.filter(
                exam=exam,
                subject_id__in=teacher_subjects,
                is_active=True
            ).select_related('subject')
            
            data = []
            for es in exam_subjects:
                # Get marks statistics
                total_students = StudentEnrollment.objects.filter(
                    academic_class=exam.academic_class, is_active=True
                ).count()
                
                marks_entered = StudentMarks.objects.filter(
                    exam_subject=es
                ).count()
                
                data.append({
                    'exam_subject_id': es.id,
                    'subject_id': es.subject.id,
                    'subject_name': es.subject.name,
                    'subject_code': es.subject.code,
                    'max_marks': es.max_marks,
                    'passing_marks': es.passing_marks,
                    'exam_date': es.exam_date,
                    'total_students': total_students,
                    'marks_entered': marks_entered,
                    'pending_count': total_students - marks_entered,
                    'completion_percentage': round((marks_entered / total_students * 100), 2) if total_students > 0 else 0,
                    'can_enter_marks': (
                        exam.status not in ('results_published', 'cancelled')
                        and es.exam_date is not None
                        and es.exam_date <= date.today()
                    )
                })
            
            return Response({
                "success": True,
                "data": {
                    "exam_info": {
                        "exam_id": exam.id,
                        "exam_name": exam.name,
                        "exam_code": exam.code,
                        "exam_status": exam.status,
                        "class_name": str(exam.academic_class)
                    },
                    "subjects": data,
                    "total_subjects": len(data)
                }
            })
            
        except Teacher.DoesNotExist:
            return Response(
                {"success": False, "message": "Teacher not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error in TeacherExamSubjectsForMarksView: {str(e)}")
            return Response(
                {"success": False, "message": str(e)},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )