# =====================================================
# TEACHER MARKS SERIALIZERS
# =====================================================

from rest_framework import serializers
from exam.models import StudentMarks, ExamSubject, Exam
from academics.models import SubjectTeacher, StudentEnrollment, AcademicClass, Subject


class TeacherSubjectClassListSerializer(serializers.Serializer):
    subject_id = serializers.IntegerField()
    subject_name = serializers.CharField()
    subject_code = serializers.CharField()
    class_id = serializers.IntegerField()
    class_name = serializers.CharField()
    standard = serializers.CharField()
    section = serializers.CharField()
    total_students = serializers.IntegerField()
    exams = serializers.ListField()


class TeacherSubjectStudentsSerializer(serializers.Serializer):
    enrollment_id = serializers.IntegerField()
    student_id = serializers.IntegerField()
    student_name = serializers.CharField()
    roll_number = serializers.IntegerField()
    admission_number = serializers.CharField(required=False, allow_null=True)
    marks_id = serializers.IntegerField(required=False, allow_null=True)
    obtained_marks = serializers.FloatField(required=False, allow_null=True)
    is_absent = serializers.BooleanField(default=False)
    is_passed = serializers.BooleanField(required=False, allow_null=True)
    percentage = serializers.FloatField(required=False, allow_null=True)
    grade = serializers.CharField(required=False, allow_null=True)
    remarks = serializers.CharField(required=False, allow_blank=True)
    has_marks = serializers.BooleanField()


class StudentMarksCreateSerializer(serializers.Serializer):
    enrollment_id = serializers.IntegerField()
    subject_id = serializers.IntegerField()
    exam_id = serializers.IntegerField()
    obtained_marks = serializers.FloatField(required=False, allow_null=True)
    is_absent = serializers.BooleanField(default=False)
    remarks = serializers.CharField(required=False, allow_blank=True)
    
    def validate_obtained_marks(self, value):
        if value is not None and value < 0:
            raise serializers.ValidationError("Marks cannot be negative")
        return value


class StudentMarksUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = StudentMarks
        fields = ['obtained_marks', 'is_absent', 'remarks']


class StudentMarksDetailSerializer(serializers.ModelSerializer):
    student_name = serializers.SerializerMethodField()
    roll_number = serializers.SerializerMethodField()
    subject_name = serializers.SerializerMethodField()
    exam_name = serializers.SerializerMethodField()
    
    class Meta:
        model = StudentMarks
        fields = [
            'id', 'student_enrollment', 'student_name', 'roll_number',
            'exam_subject', 'subject_name', 'exam_name', 'obtained_marks',
            'percentage', 'grade', 'is_passed', 'is_absent', 'remarks',
            'entry_date', 'last_updated'
        ]
    
    def get_student_name(self, obj):
        return obj.student_enrollment.student.full_name
    
    def get_roll_number(self, obj):
        return obj.student_enrollment.roll_number
    
    def get_subject_name(self, obj):
        return obj.exam_subject.subject.name
    
    def get_exam_name(self, obj):
        return obj.exam_subject.exam.name


class SubjectMarksSummarySerializer(serializers.Serializer):
    total_students = serializers.IntegerField()
    marks_entered = serializers.IntegerField()
    pending_count = serializers.IntegerField()
    highest_marks = serializers.FloatField(allow_null=True)
    lowest_marks = serializers.FloatField(allow_null=True)
    average_marks = serializers.FloatField(allow_null=True)
    pass_count = serializers.IntegerField()
    fail_count = serializers.IntegerField()
    pass_percentage = serializers.FloatField()


class BulkMarksEntrySerializer(serializers.Serializer):
    exam_id = serializers.IntegerField()
    subject_id = serializers.IntegerField()
    marks_data = serializers.ListField(
        child=serializers.DictField(),
        min_length=1
    )
    
    def validate_marks_data(self, value):
        for item in value:
            if 'enrollment_id' not in item:
                raise serializers.ValidationError("Each marks entry must have enrollment_id")
        return value


class MarksSubmissionSerializer(serializers.Serializer):
    exam_id = serializers.IntegerField()
    subject_id = serializers.IntegerField()
    submit = serializers.BooleanField(default=True)