from django.db import models
from django.conf import settings

TERM_CHOICES = [
    ('term_1', 'Term 1'),
    ('term_2', 'Term 2'),
    ('term_3', 'Term 3'),
]


class Result(models.Model):
    GRADE_A = 'A'
    GRADE_B = 'B'
    GRADE_C = 'C'
    GRADE_D = 'D'
    GRADE_F = 'F'
    GRADE_CHOICES = [
        (GRADE_A, 'A — Distinction (80–100%)'),
        (GRADE_B, 'B — Credit (65–79%)'),
        (GRADE_C, 'C — Pass (50–64%)'),
        (GRADE_D, 'D — Partial Pass (40–49%)'),
        (GRADE_F, 'F — Fail (0–39%)'),
    ]

    THEORY = 'theory'
    PRACTICAL = 'practical'
    EXAM = 'exam'
    GRADE_TYPE_CHOICES = [
        (THEORY, 'Theory'),
        (PRACTICAL, 'Practical'),
        (EXAM, 'End-of-Term Exam'),
    ]

    enrollment = models.ForeignKey(
        'admissions.Enrollment', on_delete=models.CASCADE, related_name='results'
    )
    course = models.ForeignKey(
        'courses.Course', on_delete=models.CASCADE, related_name='results'
    )
    grade = models.CharField(max_length=1, choices=GRADE_CHOICES)
    grade_type = models.CharField(max_length=10, choices=GRADE_TYPE_CHOICES, default=THEORY)
    term = models.CharField(max_length=10, choices=TERM_CHOICES)
    academic_year = models.CharField(max_length=9, help_text='e.g. 2024/2025')
    marks = models.PositiveSmallIntegerField(
        null=True, blank=True,
        help_text='Optional marks out of 100',
    )
    notes = models.TextField(blank=True)
    recorded_by = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
        null=True, blank=True, related_name='recorded_results',
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['academic_year', 'term', 'course__name']
        unique_together = [['enrollment', 'course', 'grade_type', 'term', 'academic_year']]

    def __str__(self):
        return (
            f"{self.enrollment.student.get_full_name()} — "
            f"{self.course.name} — {self.grade} ({self.get_grade_type_display()}) "
            f"{self.get_term_display()} {self.academic_year}"
        )

    @property
    def grade_color(self):
        return {
            self.GRADE_A: 'success',
            self.GRADE_B: 'primary',
            self.GRADE_C: 'info',
            self.GRADE_D: 'warning',
            self.GRADE_F: 'danger',
        }.get(self.grade, 'secondary')
