from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import *
from result.models import *
from .filters import *
from django.core.paginator import Paginator
from .forms import *
from django.contrib import messages
from django.http import HttpResponseRedirect, HttpResponse
import csv
from django.db.models import Sum
import pandas as pd
from io import TextIOWrapper

@login_required
def showSessions(request):
    if request.user.role == "Admin":
        context = {}
        filtered_sessions = SessionFilter(
            request.GET,
            queryset = Session.objects.all()
        )
        context['filtered_sessions'] = filtered_sessions
        paginated_filtered_sessions = Paginator(filtered_sessions.qs, 10)
        page_number = request.GET.get('page')
        sessions_page_obj = paginated_filtered_sessions.get_page(page_number)
        context['sessions_page_obj'] = sessions_page_obj
        total_sessions = filtered_sessions.qs.count()
        context['total_sessions'] = total_sessions
        return render(request, 'management/sessions.html', context=context)
    else:
        return redirect('index')

@login_required
def updateSessions(request, id):
    if request.user.role == "Admin":
        session = Session.objects.get(id=id)
        form = SessionForm(instance=session)
        if request.method=='POST':
            form = SessionForm(request.POST, request.FILES, instance=session)
            if form.is_valid():
                form.save()
                messages.success(request, "The session has been modified successfully")
                return redirect('sessions')
        return render(request, 'management/sessions_update.html', {'form': form, 'session': session})
    else:
        return redirect('index')

@login_required
def addSession(request):
    if request.user.role == "Admin":
        if request.method == "POST":
            form = SessionForm(request.POST, request.FILES)
            if form.is_valid():
                form.save()
                messages.success(request, "The session has been added successfully")
                return redirect('sessions')
            else:
                messages.error(request, "Please review and correct form input fields")
        else:
            form = SessionForm()
        return render(request, 'management/session.html', {'form': form})
    else:
        return redirect('index')

@login_required
def addTerm(request):
    if request.user.role == "Admin":
        if request.method == "POST":
            form = TermForm(request.POST, request.FILES, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The term has been added successfully")
                return redirect('terms')
            else:
                messages.error(request, "Please review and correct form input fields")
        else:
            form = TermForm(request=request)
        return render(request, 'management/term.html', {'form': form})
    else:
        return redirect('index')

@login_required
def showTerms(request):
    if request.user.role == "Admin":
        context = {}
        filtered_terms = TermFilter(
            request.GET,
            queryset = Term.objects.all()
        )
        context['filtered_terms'] = filtered_terms
        paginated_filtered_terms = Paginator(filtered_terms.qs, 10)
        page_number = request.GET.get('page')
        terms_page_obj = paginated_filtered_terms.get_page(page_number)
        context['terms_page_obj'] = terms_page_obj
        total_terms = filtered_terms.qs.count()
        context['total_terms'] = total_terms
        return render(request, 'management/terms.html', context=context)
    if request.user.role == "Student":
        context = {}
        filtered_terms = TermFilter(
            request.GET,
            queryset = Term.objects.all()
        )
        context['filtered_terms'] = filtered_terms
        paginated_filtered_terms = Paginator(filtered_terms.qs, 10)
        page_number = request.GET.get('page')
        terms_page_obj = paginated_filtered_terms.get_page(page_number)
        context['terms_page_obj'] = terms_page_obj
        total_terms = filtered_terms.qs.count()
        context['total_terms'] = total_terms
        return render(request, 'payment/terms_student.html', context=context)

    else:
        return redirect('index')

@login_required
def updateTerms(request, id):
    if request.user.role == "Admin":
        term = Term.objects.get(id=id)
        form = TermFormUpdate(instance=term, request=request)
        if request.method=='POST':
            form = TermFormUpdate(request.POST, request.FILES, instance=term, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The term has been modified successfully")
                return redirect('terms')
        return render(request, 'management/terms_update.html', {'form': form, 'term': term})
    else:
        return redirect('index')

@login_required
def showClasses(request):
    if request.user.role == "Admin":
        context = {}
        filtered_classes = ClassFilter(
            request.GET,
            queryset = Class.objects.all()
        )
        context['filtered_classes'] = filtered_classes
        paginated_filtered_classes = Paginator(filtered_classes.qs, 10)
        page_number = request.GET.get('page')
        classes_page_obj = paginated_filtered_classes.get_page(page_number)
        context['classes_page_obj'] = classes_page_obj
        total_classes = filtered_classes.qs.count()
        context['total_classes'] = total_classes
        return render(request, 'management/classes.html', context=context)
    else:
        return redirect('index')

@login_required
def updateClasses(request, id):
    if request.user.role == "Admin":
        classe = Class.objects.get(id=id)
        form = ClassFormUpdate(instance=classe, request=request)
        if request.method=='POST':
            form = ClassFormUpdate(request.POST, request.FILES, instance=classe, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The class has been modified successfully")
                return redirect('classes')
        return render(request, 'management/classes_update.html', {'form': form, 'classe': classe})
    else:
        return redirect('index')

@login_required
def addClass(request):
    if request.user.role == "Admin":
        if request.method == "POST":
            form = ClassForm(request.POST, request.FILES, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The class has been added successfully")
                return redirect('classes')
            else:
                messages.error(request, "Please review and correct form input fields")
        else:
            form = ClassForm(request=request)
        return render(request, 'management/class.html', {'form': form})
    else:
        return redirect('index')

@login_required
def showSubjects(request):
    if request.user.role == "Admin":
        context = {}
        filtered_subjects = SubjectFilter(
            request.GET,
            queryset = Subject.objects.all()
        )
        context['filtered_subjects'] = filtered_subjects
        paginated_filtered_subjects = Paginator(filtered_subjects.qs, 10)
        page_number = request.GET.get('page')
        subjects_page_obj = paginated_filtered_subjects.get_page(page_number)
        context['subjects_page_obj'] = subjects_page_obj
        total_subjects = filtered_subjects.qs.count()
        context['total_subjects'] = total_subjects
        return render(request, 'management/subjects.html', context=context)
    else:
        return redirect('index')

@login_required
def updateSubjects(request, id):
    if request.user.role == "Admin":
        subject = Subject.objects.get(id=id)
        form = SubjectFormUpdate(instance=subject, request=request)
        if request.method=='POST':
            form = SubjectFormUpdate(request.POST, request.FILES, instance=subject, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The subject has been modified successfully")
                return redirect('subjects')
        return render(request, 'management/subjects_update.html', {'form': form, 'subject': subject})
    else:
        return redirect('index')

@login_required
def addSubject(request):
    if request.user.role == "Admin":
        if request.method == "POST":
            form = SubjectForm(request.POST, request.FILES, request=request)
            if form.is_valid():
                form.save()
                messages.success(request, "The subject has been added successfully")
                return redirect('subjects')
            else:
                messages.error(request, "Please review and correct form input fields")
        else:
            form = SubjectForm(request=request)
        return render(request, 'management/subject.html', {'form': form})
    else:
        return redirect('index')

@login_required
def showTeachersSubjectsEarly(request):
    if request.user.role == "Staff":
        context = {}
        filtered_subjects = TeacherSubjectFilter(
            request.GET,
            queryset = Subject.objects.filter(teacher=request.user, classe__section="Nursery")
        )
        context['filtered_subjects'] = filtered_subjects
        paginated_filtered_subjects = Paginator(filtered_subjects.qs, 10)
        page_number = request.GET.get('page')
        subjects_page_obj = paginated_filtered_subjects.get_page(page_number)
        context['subjects_page_obj'] = subjects_page_obj
        total_subjects = filtered_subjects.qs.count()
        context['total_subjects'] = total_subjects
        return render(request, 'management/teachers_subjects_early.html', context=context)
    else:
        return redirect('index')

@login_required
def showTeachersSubjectsGrade(request):
    if request.user.role == "Staff":
        context = {}
        filtered_subjects = TeacherSubjectFilter(
            request.GET,
            queryset = Subject.objects.filter(teacher=request.user, classe__section="Primary")
        )
        context['filtered_subjects'] = filtered_subjects
        paginated_filtered_subjects = Paginator(filtered_subjects.qs, 10)
        page_number = request.GET.get('page')
        subjects_page_obj = paginated_filtered_subjects.get_page(page_number)
        context['subjects_page_obj'] = subjects_page_obj
        total_subjects = filtered_subjects.qs.count()
        context['total_subjects'] = total_subjects
        return render(request, 'management/teachers_subjects_grade.html', context=context)
    else:
        return redirect('index')

@login_required
def showTeachersSubjectsSecondary(request):
    if request.user.role == "Staff":
        context = {}
        filtered_subjects = TeacherSubjectFilter(
            request.GET,
            queryset = Subject.objects.filter(teacher=request.user, classe__section="Secondary")
        )
        context['filtered_subjects'] = filtered_subjects
        paginated_filtered_subjects = Paginator(filtered_subjects.qs, 10)
        page_number = request.GET.get('page')
        subjects_page_obj = paginated_filtered_subjects.get_page(page_number)
        context['subjects_page_obj'] = subjects_page_obj
        total_subjects = filtered_subjects.qs.count()
        context['total_subjects'] = total_subjects
        return render(request, 'management/teachers_subjects_secondary.html', context=context)
    else:
        return redirect('index')

@login_required
def downloadCSVEarly(request, id):
    if request.user.role == "Staff":
        subject = Subject.objects.get(id=id)
        students = Person.objects.filter(role="Student", classe=subject.classe).order_by('username')
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=Students for ' + str(subject.subject) + ' - ' + str(subject.classe) + '.csv'

        writer = csv.writer(response)
        writer.writerow(['Admission Number', "Names of Students", 'Class', 'Subject', '1st CA', '2nd CA', 'Exam'])

        for each in students:
            writer.writerow(
                [each.username, str(each.first_name) + " " + str(each.last_name), each.classe, subject.subject]
            )
        return response
    else:
        return redirect('index')

@login_required
def downloadCSVGrade(request, id):
    if request.user.role == "Staff":
        subject = Subject.objects.get(id=id)
        students = Person.objects.filter(role="Student", classe=subject.classe).order_by('username')
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=Students for ' + str(subject.subject) + ' - ' + str(subject.classe) + '.csv'

        writer = csv.writer(response)
        writer.writerow(['Admission Number', "Names of Students", 'Class', 'Subject', '1st CA', '2nd CA', 'Exam'])

        for each in students:
            writer.writerow(
                [each.username, str(each.first_name) + " " + str(each.last_name), each.classe, subject.subject]
            )
        return response
    else:
        return redirect('index')

@login_required
def downloadCSVSecondary(request, id):
    if request.user.role == "Staff":
        subject = Subject.objects.get(id=id)
        students = Person.objects.filter(role="Student", classe=subject.classe).order_by('username')
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=Students for ' + str(subject.subject) + ' - ' + str(subject.classe) + '.csv'

        writer = csv.writer(response)
        writer.writerow(['Admission Number', "Names of Students", 'Class', 'Subject', '1st CA', '2nd CA', 'Exam'])

        for each in students:
            writer.writerow(
                [each.username, str(each.first_name) + " " + str(each.last_name), each.classe, subject.subject]
            )
        return response
    else:
        return redirect('index')
#
# def to_int(value):
#     if value is None:
#         return 0
#     value = str(value).strip()
#     if value == "":
#         return 0
#     try:
#         return int(float(value))
#     except ValueError:
#         return 0

def to_int(value):
    try:
        if value is None:
            return 0
        if isinstance(value, str):
            value = value.strip()
            if value == "":
                return 0
        return int(float(value))
    except Exception:
        return 0

@login_required
def uploadCSVEarly(request, id):
    subject = Subject.objects.get(id=id)
    if subject.teacher == request.user:
        term = Term.objects.get(current=True)

        if subject in term.subject_recorded.all():
            messages.error(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
            return redirect('teachers_subjects_early')
        else:
            if request.method == 'GET':
                form = UploadForm()
                return render(request, 'management/upload.html', {'form': form, 'subject':subject, 'term':term})

            form = UploadForm(request.POST, request.FILES)
            # Validate the form
            if not form.is_valid():

                return redirect('index')

            uploaded_file = request.FILES['sent_file']
            file_name = uploaded_file.name.lower()

            if file_name.endswith('.csv'):
                csv_file = TextIOWrapper(uploaded_file.file, encoding='utf-8-sig')
                data = csv.DictReader(csv_file)

            elif file_name.endswith(('.xls', '.xlsx')):
                df = pd.read_excel(uploaded_file)
                df = df.fillna("")  # very important
                data = df.to_dict(orient='records')

            else:
                messages.error(request, "Unsupported file format. Upload CSV or Excel.")
                return redirect('teachers_subjects_early')

            errors = []
            success_count = 0

            for index, row in enumerate(data, start=2):  # start=2 (header is row 1)
                try:
                    admission_no = row.get('Admission Number')
                    d_classe = row.get('Class')
                    d_subject = row.get('Subject')

                    if not admission_no:
                        raise ValueError("Missing Admission Number")

                    test  = to_int(row.get('1st CA'))
                    test2 = to_int(row.get('2nd CA'))
                    exam  = to_int(row.get('Exam'))

                    e_subject = Subject.objects.get(classe__classe=d_classe, subject=d_subject)
                    # if subject != e_subject:
                    #     messages.error(request, "You're trying to upload " +str(e_subject.subject)+ " sheet into " +str(subject.subject))
                    #     return redirect('teachers_subjects_early')

                    if subject != e_subject:
                        raise ValueError(
                            f"Wrong subject. Expected {subject.subject}, but you uploaded for {e_subject.subject}"
                        )

                    stud = Person.objects.get(username=admission_no)
                    class_students_count = Person.objects.filter(classe=stud.classe).count()

                    p = Early()
                    p.term = term
                    p.student = stud
                    p.subject = subject
                    p.test = test
                    p.test2 = test2
                    p.exam = exam

                    p.total = test + test2 + exam
                    p.obtainable = 100
                    total = test + test2 + exam
                    p.save()

                    success_count += 1
                except Person.DoesNotExist:
                    errors.append(f"Row {index}: Student with admission number '{admission_no}' not found")

                except Subject.DoesNotExist:
                    errors.append(f"Row {index}: Subject/Class mismatch")

                except ValueError as e:
                    errors.append(f"Row {index}: {str(e)}")

                except Exception as e:
                    errors.append(f"Row {index}: Unexpected error → {str(e)}")

                try:
                    reg7 = Early.objects.get(term=term, student=stud)
                    reg7.value = 1
                    reg7.save()
                except:
                    pass
                reg4 = Early.objects.filter(term=term, subject=subject).order_by('-total')
                n = reg4.count()
                try:
                    reg3 = Early.objects.filter(term=term, subject=subject)[1]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Early.objects.filter(term=term, subject=subject)[1]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                except:
                    reg3 = Early.objects.filter(term=term, subject=subject)[0]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Early.objects.filter(term=term, subject=subject)[0]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                for each in reg4:
                    each.subject_total = reg5.subject_total
                    each.subject_avg = d
                    each.grade = reg5.grade()
                    each.save()

                for each in reg4:
                    subject_position.append(each.total)

                for i in range(len(subject_position)):
                    for each in reg4:
                        temp = subject_position.index(each.total)
                        each.subject_pos = temp + 1
                        each.save()

                reg6 = Early.objects.filter(term=term, student=stud)
                m = reg6.count()
                all_total = Early.objects.filter(term=term, student=stud).aggregate(Sum('total'))['total__sum']
                all_obtainable = Early.objects.filter(term=term, student=stud).aggregate(Sum('obtainable'))['obtainable__sum']
                cum_perc = round((all_total/m),2)
                for each in reg6:
                    each.cumulative = all_total
                    each.all_obtainable = all_obtainable
                    each.cum_perc = cum_perc
                    each.static_class = str(each.student.classe)
                    each.static_class_teacher = str(each.student.classe.teacher.first_name) + " " + str(each.student.classe.teacher.last_name)
                    each.static_head_teacher = str(each.term.head.first_name) + " " + str(each.term.head.last_name)
                    each.static_teacher_signature = each.student.classe.signature
                    each.static_student_image = each.student.photograph
                    each.static_age = each.student.age()
                    each.static_number_in_class = class_students_count
                    each.number_absent = term.number - each.number_present
                    each.save()

            if errors:
                for err in errors[:10]:  # show only first 10
                    messages.success(request, err)

                if len(errors) > 10:
                    messages.success(
                        request,
                        f"{len(errors)} total errors occurred. Fix them and re-upload."
                    )

            if success_count > 0:
                messages.success(
                    request,
                    f"{success_count} records uploaded successfully."
                )
            # messages.success(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
                term.subject_recorded.add(subject)

            return redirect('teachers_subjects_early')

@login_required
def uploadCSVGrade(request, id):
    subject = Subject.objects.get(id=id)
    if subject.teacher == request.user:
        term = Term.objects.get(current=True)

        if subject in term.subject_recorded.all():
            messages.error(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
            return redirect('teachers_subjects_grade')
        else:
            if request.method == 'GET':
                form = UploadForm()
                return render(request, 'management/upload.html', {'form': form, 'subject':subject, 'term':term})

            form = UploadForm(request.POST, request.FILES)
            # Validate the form
            if not form.is_valid():

                return redirect('index')

            uploaded_file = request.FILES['sent_file']
            file_name = uploaded_file.name.lower()

            if file_name.endswith('.csv'):
                csv_file = TextIOWrapper(uploaded_file.file, encoding='utf-8-sig')
                data = csv.DictReader(csv_file)

            elif file_name.endswith(('.xls', '.xlsx')):
                df = pd.read_excel(uploaded_file)
                df = df.fillna("")  # very important
                data = df.to_dict(orient='records')

            else:
                messages.error(request, "Unsupported file format. Upload CSV or Excel.")
                return redirect('teachers_subjects_grade')

            errors = []
            success_count = 0

            for index, row in enumerate(data, start=2):  # start=2 (header is row 1)
                try:
                    admission_no = row.get('Admission Number')
                    d_classe = row.get('Class')
                    d_subject = row.get('Subject')

                    if not admission_no:
                        raise ValueError("Missing Admission Number")

                    test  = to_int(row.get('1st CA'))
                    test2 = to_int(row.get('2nd CA'))
                    exam  = to_int(row.get('Exam'))

                    e_subject = Subject.objects.get(classe__classe=d_classe, subject=d_subject)
                    # if subject != e_subject:
                    #     messages.error(request, "You're trying to upload " +str(e_subject.subject)+ " sheet into " +str(subject.subject))
                    #     return redirect('teachers_subjects_grade')

                    if subject != e_subject:
                        raise ValueError(
                            f"Wrong subject. Expected {subject.subject}, but you uploaded for {e_subject.subject}"
                        )

                    stud = Person.objects.get(username=admission_no)
                    class_students_count = Person.objects.filter(classe=stud.classe).count()

                    p = Grade()
                    p.term = term
                    p.student = stud
                    p.subject = subject
                    p.test = test
                    p.test2 = test2
                    p.exam = exam

                    p.total = test + test2 + exam
                    p.obtainable = 100
                    total = test + test2 + exam
                    p.save()

                    success_count += 1
                except Person.DoesNotExist:
                    errors.append(f"Row {index}: Student with admission number '{admission_no}' not found")

                except Subject.DoesNotExist:
                    errors.append(f"Row {index}: Subject/Class mismatch")

                except ValueError as e:
                    errors.append(f"Row {index}: {str(e)}")

                except Exception as e:
                    errors.append(f"Row {index}: Unexpected error → {str(e)}")

                try:
                    reg7 = Grade.objects.get(term=term, student=stud)
                    reg7.value = 1
                    reg7.save()
                except:
                    pass
                reg4 = Grade.objects.filter(term=term, subject=subject).order_by('-total')
                n = reg4.count()
                try:
                    reg3 = Grade.objects.filter(term=term, subject=subject)[1]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Grade.objects.filter(term=term, subject=subject)[1]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                except:
                    reg3 = Grade.objects.filter(term=term, subject=subject)[0]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Grade.objects.filter(term=term, subject=subject)[0]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                for each in reg4:
                    each.subject_total = reg5.subject_total
                    each.subject_avg = d
                    each.grade = reg5.grade()
                    each.save()

                for each in reg4:
                    subject_position.append(each.total)

                for i in range(len(subject_position)):
                    for each in reg4:
                        temp = subject_position.index(each.total)
                        each.subject_pos = temp + 1
                        each.save()

                reg6 = Grade.objects.filter(term=term, student=stud)
                m = reg6.count()
                all_total = Grade.objects.filter(term=term, student=stud).aggregate(Sum('total'))['total__sum']
                all_obtainable = Grade.objects.filter(term=term, student=stud).aggregate(Sum('obtainable'))['obtainable__sum']
                cum_perc = round((all_total/m),2)
                for each in reg6:
                    each.cumulative = all_total
                    each.all_obtainable = all_obtainable
                    each.cum_perc = cum_perc
                    each.static_class = str(each.student.classe)
                    each.static_class_teacher = str(each.student.classe.teacher.first_name) + " " + str(each.student.classe.teacher.last_name)
                    each.static_head_teacher = str(each.term.head.first_name) + " " + str(each.term.head.last_name)
                    each.static_teacher_signature = each.student.classe.signature
                    each.static_student_image = each.student.photograph
                    each.static_age = each.student.age()
                    each.static_number_in_class = class_students_count
                    each.number_absent = term.number - each.number_present
                    each.save()

            if errors:
                for err in errors[:10]:  # show only first 10
                    messages.success(request, err)

                if len(errors) > 10:
                    messages.success(
                        request,
                        f"{len(errors)} total errors occurred. Fix them and re-upload."
                    )

            if success_count > 0:
                messages.success(
                    request,
                    f"{success_count} records uploaded successfully."
                )
            # messages.success(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
                term.subject_recorded.add(subject)

            return redirect('teachers_subjects_grade')

@login_required
def uploadCSVSecondary(request, id):
    subject = Subject.objects.get(id=id)
    if subject.teacher == request.user:
        term = Term.objects.get(current=True)

        if subject in term.subject_recorded.all():
            messages.error(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
            return redirect('teachers_subjects_secondary')
        else:
            if request.method == 'GET':
                form = UploadForm()
                return render(request, 'management/upload.html', {'form': form, 'subject':subject, 'term':term})

            form = UploadForm(request.POST, request.FILES)
            # Validate the form
            if not form.is_valid():

                return redirect('index')

            uploaded_file = request.FILES['sent_file']
            file_name = uploaded_file.name.lower()

            if file_name.endswith('.csv'):
                csv_file = TextIOWrapper(uploaded_file.file, encoding='utf-8-sig')
                data = csv.DictReader(csv_file)

            elif file_name.endswith(('.xls', '.xlsx')):
                df = pd.read_excel(uploaded_file)
                df = df.fillna("")  # very important
                data = df.to_dict(orient='records')

            else:
                messages.error(request, "Unsupported file format. Upload CSV or Excel.")
                return redirect('teachers_subjects_secondary')

            errors = []
            success_count = 0

            for index, row in enumerate(data, start=2):  # start=2 (header is row 1)
                try:
                    admission_no = row.get('Admission Number')
                    d_classe = row.get('Class')
                    d_subject = row.get('Subject')

                    if not admission_no:
                        raise ValueError("Missing Admission Number")

                    test  = to_int(row.get('1st CA'))
                    test2 = to_int(row.get('2nd CA'))
                    exam  = to_int(row.get('Exam'))

                    e_subject = Subject.objects.get(classe__classe=d_classe, subject=d_subject)
                    # if subject != e_subject:
                    #     messages.error(request, "You're trying to upload " +str(e_subject.subject)+ " sheet into " +str(subject.subject))
                    #     return redirect('teachers_subjects_secondary')

                    if subject != e_subject:
                        raise ValueError(
                            f"Wrong subject. Expected {subject.subject}, but you uploaded for {e_subject.subject}"
                        )

                    stud = Person.objects.get(username=admission_no)
                    class_students_count = Person.objects.filter(classe=stud.classe).count()

                    p = Secondary()
                    p.term = term
                    p.student = stud
                    p.subject = subject
                    p.test = test
                    p.test2 = test2
                    p.exam = exam

                    p.total = test + test2 + exam
                    p.obtainable = 100
                    total = test + test2 + exam
                    p.save()

                    success_count += 1
                except Person.DoesNotExist:
                    errors.append(f"Row {index}: Student with admission number '{admission_no}' not found")

                except Subject.DoesNotExist:
                    errors.append(f"Row {index}: Subject/Class mismatch")

                except ValueError as e:
                    errors.append(f"Row {index}: {str(e)}")

                except Exception as e:
                    errors.append(f"Row {index}: Unexpected error → {str(e)}")

                try:
                    reg7 = Secondary.objects.get(term=term, student=stud)
                    reg7.value = 1
                    reg7.save()
                except:
                    pass
                reg4 = Secondary.objects.filter(term=term, subject=subject).order_by('-total')
                n = reg4.count()
                try:
                    reg3 = Secondary.objects.filter(term=term, subject=subject)[1]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Secondary.objects.filter(term=term, subject=subject)[1]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                except:
                    reg3 = Secondary.objects.filter(term=term, subject=subject)[0]
                    reg3.subject_total = reg3.subject_total + total
                    reg3.save()
                    reg5 = Secondary.objects.filter(term=term, subject=subject)[0]
                    d = round((reg5.subject_total/n),2)
                    subject_position = []
                for each in reg4:
                    each.subject_total = reg5.subject_total
                    each.subject_avg = d
                    each.grade = reg5.grade()
                    each.save()

                for each in reg4:
                    subject_position.append(each.total)

                for i in range(len(subject_position)):
                    for each in reg4:
                        temp = subject_position.index(each.total)
                        each.subject_pos = temp + 1
                        each.save()

                reg6 = Secondary.objects.filter(term=term, student=stud)
                m = reg6.count()
                all_total = Secondary.objects.filter(term=term, student=stud).aggregate(Sum('total'))['total__sum']
                all_obtainable = Secondary.objects.filter(term=term, student=stud).aggregate(Sum('obtainable'))['obtainable__sum']
                cum_perc = round((all_total/m),2)
                for each in reg6:
                    each.cumulative = all_total
                    each.all_obtainable = all_obtainable
                    each.cum_perc = cum_perc
                    each.static_class = str(each.student.classe)
                    each.static_class_teacher = str(each.student.classe.teacher.first_name) + " " + str(each.student.classe.teacher.last_name)
                    each.static_head_teacher = str(each.term.head2.first_name) + " " + str(each.term.head2.last_name)
                    each.static_teacher_signature = each.student.classe.signature
                    each.static_student_image = each.student.photograph
                    each.static_age = each.student.age()
                    each.static_number_in_class = class_students_count
                    each.number_absent = term.number - each.number_present
                    each.save()

            if errors:
                for err in errors[:10]:  # show only first 10
                    messages.success(request, err)

                if len(errors) > 10:
                    messages.success(
                        request,
                        f"{len(errors)} total errors occurred. Fix them and re-upload."
                    )

            if success_count > 0:
                messages.success(
                    request,
                    f"{success_count} records uploaded successfully."
                )
            # messages.success(request, "Scores have been uploaded for " +str(subject.subject)+ " for the term")
                term.subject_recorded.add(subject)

            return redirect('teachers_subjects_secondary')

@login_required
def showAdminSpreadsheets(request):
    if request.user.role == 'Admin':
        context = {}
        filtered_classes = ClassFilter2(
            request.GET,
            queryset = Spreadsheet.objects.all().order_by('classe__classe')
        )
        context['filtered_classes'] = filtered_classes
        paginated_filtered_classes = Paginator(filtered_classes.qs, 50)
        page_number = request.GET.get('page')
        classes_page_obj = paginated_filtered_classes.get_page(page_number)
        context['classes_page_obj'] = classes_page_obj
        total_classes = filtered_classes.qs.count()
        context['total_classes'] = total_classes
        return render(request, 'management/admin_spreadsheets.html', context=context)
    else:
        return redirect('index')

@login_required
def addSpreadsheet(request):
    form = SpreadsheetForm()
    if request.method=='POST':
        form = SpreadsheetForm(request.POST or None)
        if form.is_valid():
            form.save()
            term = form.cleaned_data.get('term')
            classes = Class.objects.all()
            for each in classes:
                new_entry = Spreadsheet()
                new_entry.classe = each
                new_entry.term = term
                new_entry.save()

            reg = Spreadsheet.objects.get(classe=None)
            reg.delete()
            messages.success(request, "All classes' spreadsheets have been created successfully")
        else:
            messages.error(request, "Please review form input fields below")
    return render(request, 'management/spreadsheet.html', {'form': form})

@login_required
def showAdminSpreadsheet(request, id):
    if request.user.role=="Admin":
        spreadsheet = Spreadsheet.objects.get(id=id)
        classe = spreadsheet.classe
        term = spreadsheet.term
        if classe.section == "Nursery":
            earlys = Early.objects.filter(term=term, static_class=classe.classe)
        elif classe.section == "Primary":
            earlys = Grade.objects.filter(term=term, static_class=classe.classe)
        elif classe.section == "Secondary":
            earlys = Secondary.objects.filter(term=term, static_class=classe.classe)

        class_students_list = []
        student_list = []
        for each in earlys:
            if each.student not in student_list:
                student_list.append(each.student)
                class_students_list.append(each)

        class_students_count = len(class_students_list)
    return render(request, 'management/admin_spreadsheet.html', {'earlys':earlys, 'class_students_list':class_students_list,
    'class_students_count':class_students_count})
