from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db import models

from secondary.models.assessments import ContinuousAssessmentRecord
from secondary.models.policies import SecondaryComputationPolicy


class UNEBSubmissionBatch(models.Model):
    class Status(models.TextChoices):
        DRAFT = "DRAFT", "Draft"
        PENDING_APPROVAL = "PENDING_APPROVAL", "Pending Approval"
        APPROVED = "APPROVED", "Approved"
        SUBMITTED = "SUBMITTED", "Submitted to UNEB"
        LOCKED = "LOCKED", "Locked"
        REJECTED = "REJECTED", "Rejected"

    title = models.CharField(max_length=150, default="S4 UNEB CA Submission")
    academic_year = models.ForeignKey("app.AcademicYear", on_delete=models.CASCADE, related_name="uneb_ca_batches")
    section = models.ForeignKey("app.Section", on_delete=models.CASCADE, related_name="uneb_ca_batches")
    level = models.CharField(
        max_length=30,
        choices=SecondaryComputationPolicy.Level.choices,
        default=SecondaryComputationPolicy.Level.LOWER_SECONDARY,
    )
    candidate_class = models.ForeignKey(
        "app.Class",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="uneb_ca_batches",
    )
    status = models.CharField(max_length=25, choices=Status.choices, default=Status.DRAFT)
    submission_reference = models.CharField(max_length=100, blank=True, default="")
    notes = models.TextField(blank=True, null=True)
    created_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="uneb_ca_batches_created",
    )
    approved_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="uneb_ca_batches_approved",
    )
    submitted_by = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="uneb_ca_batches_submitted",
    )
    approved_at = models.DateTimeField(null=True, blank=True)
    submitted_at = models.DateTimeField(null=True, blank=True)
    locked_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        db_table = "app_unebsubmissionbatch"

    def __str__(self):
        return f"{self.title} - {self.academic_year}"


class UNEBSubmissionItem(models.Model):
    batch = models.ForeignKey(UNEBSubmissionBatch, on_delete=models.CASCADE, related_name="items")
    student = models.ForeignKey("app.Student", on_delete=models.CASCADE, related_name="uneb_ca_items")
    subject = models.ForeignKey("app.Subject", on_delete=models.CASCADE, related_name="uneb_ca_items")
    ca_mark = models.DecimalField(max_digits=5, decimal_places=2)
    final_ca_mark = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    source_task_count = models.PositiveIntegerField(default=0)
    evidence_count = models.PositiveIntegerField(default=0)
    moderation_status = models.CharField(
        max_length=20,
        choices=ContinuousAssessmentRecord.ModerationStatus.choices,
        default=ContinuousAssessmentRecord.ModerationStatus.PENDING,
    )
    is_locked = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ("batch", "student", "subject")
        ordering = ["student_id", "subject_id"]
        db_table = "app_unebsubmissionitem"

    def __str__(self):
        return f"{self.student} - {self.subject} ({self.final_ca_mark or self.ca_mark})"

    def clean(self):
        mark = self.final_ca_mark if self.final_ca_mark is not None else self.ca_mark
        if mark < 0 or mark > 100:
            raise ValidationError("Submitted CA mark must be between 0 and 100.")
        if self.batch_id and self.subject_id and self.batch.section_id != self.subject.section_id:
            raise ValidationError("Submission item subject section must match submission batch section.")
