from django.db import models
from django_jsonform.models.fields import JSONField as JSONSchemaField

from vbv_lernwelt.assignment.models import AssignmentType
from vbv_lernwelt.duedate.models import DueDate
from vbv_lernwelt.learnpath.models import Circle


class CourseSessionAttendanceCourse(models.Model):
    """
    Präsenztag Durchührung

    Kann über einen Zeitraum von meheren Tagen gehen.
    """

    course_session = models.ForeignKey(
        "course.CourseSession",
        on_delete=models.CASCADE,
    )
    learning_content = models.ForeignKey(
        "learnpath.LearningContentAttendanceCourse",
        on_delete=models.CASCADE,
    )
    due_date = models.OneToOneField(
        "duedate.DueDate",
        on_delete=models.CASCADE,
        related_name="attendance_course_due_date",
    )

    location = models.CharField(max_length=255, blank=True, default="")
    trainer = models.CharField(max_length=255, blank=True, default="")

    class Meta:
        ordering = ["course_session", "due_date__start"]

    # because the attendance list is more of a snapshot of the current state
    # we will store the attendance list as a JSONField
    # the important field of the list type is "user_id"
    ATTENDANCE_USER_LIST_SCHEMA = {
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
                "user_id": {
                    "type": "number",
                    "required": True,
                },
                "email": {"type": "string"},
                "first_name": {"type": "string"},
                "last_name": {"type": "string"},
            },
        },
    }
    attendance_user_list = JSONSchemaField(
        default=list, schema=ATTENDANCE_USER_LIST_SCHEMA
    )

    def save(self, *args, **kwargs):
        if self.learning_content_id:
            if not self.due_date_id:
                self.due_date = DueDate.objects.create(
                    course_session=self.course_session,
                )

            if not self.due_date.manual_override_fields:
                self.due_date.url = self.learning_content.get_frontend_url(
                    course_session_id=self.course_session.id
                )
                self.due_date.url_expert = f"/course/{self.due_date.course_session.course.slug}/cockpit/attendance?id={self.learning_content_id}&courseSessionId={self.course_session.id}"
                self.due_date.title = self.learning_content.title
                self.due_date.page = self.learning_content.page_ptr
                self.due_date.assignment_type_translation_key = (
                    "learningContentTypes.attendanceCourse"
                )

                self.due_date.save()

        super().save(*args, **kwargs)

    def get_circle(self):
        try:
            return self.learning_content.get_ancestors().exact_type(Circle).first()
        except Exception:
            # noop
            pass
        return None

    def __str__(self):
        return f"{self.course_session} - {self.learning_content}"


class CourseSessionAssignment(models.Model):
    """
    Auftrag
    - Geleitete Fallarbeit ist eine spezifische Ausprägung eines Auftrags (assignment_type)

    """

    course_session = models.ForeignKey(
        "course.CourseSession",
        on_delete=models.CASCADE,
    )
    learning_content = models.ForeignKey(
        "learnpath.LearningContentAssignment",
        on_delete=models.CASCADE,
    )
    submission_deadline = models.OneToOneField(
        "duedate.DueDate",
        on_delete=models.CASCADE,
        related_name="assignment_submission_deadline",
        null=True,
        blank=True,
    )

    evaluation_deadline = models.OneToOneField(
        "duedate.DueDate",
        on_delete=models.CASCADE,
        related_name="assignment_evaluation_deadline",
        null=True,
        blank=True,
    )

    class Meta:
        ordering = ["course_session", "submission_deadline__start"]

    def save(self, *args, **kwargs):
        if self.learning_content_id:
            title = self.learning_content.title
            page = self.learning_content.page_ptr
            url = self.learning_content.get_frontend_url(
                course_session_id=self.course_session.id
            )
            assignment_type = self.learning_content.assignment_type
            assignment_type_translation_keys = {
                AssignmentType.CASEWORK.value: "learningContentTypes.casework",
                AssignmentType.PRAXIS_ASSIGNMENT.value: "learningContentTypes.praxisAssignment",
                AssignmentType.PREP_ASSIGNMENT.value: "learningContentTypes.prepAssignment",
                AssignmentType.REFLECTION.value: "learningContentTypes.reflection",
            }

            url_expert = f"/course/{self.course_session.course.slug}/cockpit/assignment/{self.learning_content_id}?courseSessionId={self.course_session.id}"

            if assignment_type in (
                AssignmentType.CASEWORK.value,
                AssignmentType.PREP_ASSIGNMENT.value,
            ):
                if not self.submission_deadline_id:
                    self.submission_deadline = DueDate.objects.create(
                        course_session=self.course_session,
                    )

                if not self.submission_deadline.manual_override_fields:
                    self.submission_deadline.url = url
                    self.submission_deadline.url_expert = url_expert
                    self.submission_deadline.title = title
                    self.submission_deadline.assignment_type_translation_key = (
                        assignment_type_translation_keys[assignment_type]
                    )
                    self.submission_deadline.date_type_translation_key = (
                        "assignment.dueDateSubmission"
                    )
                    self.submission_deadline.page = page

                    self.submission_deadline.save()

            if assignment_type == AssignmentType.CASEWORK.value:
                if not self.evaluation_deadline_id:
                    self.evaluation_deadline = DueDate.objects.create(
                        course_session=self.course_session,
                    )

                if not self.evaluation_deadline.manual_override_fields:
                    self.evaluation_deadline.url = url
                    self.evaluation_deadline.url_expert = url_expert
                    self.evaluation_deadline.title = title
                    self.evaluation_deadline.assignment_type_translation_key = (
                        assignment_type_translation_keys[assignment_type]
                    )
                    self.evaluation_deadline.date_type_translation_key = (
                        "assignment.dueDateEvaluation"
                    )
                    self.evaluation_deadline.page = page

                    self.evaluation_deadline.save()

        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.course_session} - {self.learning_content}"


class CourseSessionEdoniqTest(models.Model):
    course_session = models.ForeignKey(
        "course.CourseSession",
        on_delete=models.CASCADE,
    )
    learning_content = models.ForeignKey(
        "learnpath.LearningContentEdoniqTest",
        on_delete=models.CASCADE,
    )
    deadline = models.OneToOneField(
        "duedate.DueDate",
        on_delete=models.CASCADE,
        related_name="test_submission_deadline",
        null=True,
    )

    class Meta:
        ordering = ["course_session", "deadline__start"]

    def __str__(self):
        return f"{self.course_session} - {self.learning_content}"

    def save(self, *args, **kwargs):
        if self.learning_content_id:
            if not self.deadline_id:
                self.deadline = DueDate.objects.create(
                    course_session=self.course_session,
                )

            if not self.deadline.manual_override_fields:
                self.deadline.url = self.learning_content.get_frontend_url(
                    course_session_id=self.course_session.id
                )
                self.deadline.url_expert = f"/course/{self.course_session.course.slug}/cockpit/assignment/{self.learning_content_id}?courseSessionId={self.course_session.id}"
                self.deadline.title = self.learning_content.title
                self.deadline.page = self.learning_content.page_ptr
                self.deadline.assignment_type_translation_key = (
                    "learningContentTypes.edoniqTest"
                )
                self.deadline.date_type_translation_key = "assignment.dueDateSubmission"

                self.deadline.save()

        super().save(*args, **kwargs)
