from datetime import timedelta

from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
from markdownx.models import MarkdownxField

from shared.models import NameStrMixin

# Create your models here.


class LectureGroup(NameStrMixin, models.Model):
    name = models.CharField(
        max_length=128,
        verbose_name="Jméno",
    )

    description = MarkdownxField(
        null=True,
        blank=True,
        verbose_name="Popis",
        help_text="Můžeš použít Markdown.",
    )

    user_groups = models.ManyToManyField(
        Group,
        blank=True,
        verbose_name="Uživatelské skupiny",
        help_text="Pokud nedefinuješ žádné, lekce ve skupině jsou dostupné všem.",
    )

    class Meta:
        verbose_name = "Výuková skupina"
        verbose_name_plural = "Výukové skupiny"
        ordering = ("name",)


class Lecture(NameStrMixin, models.Model):
    is_current_treshold = timedelta(hours=8)

    timestamp = models.DateTimeField(
        verbose_name="Datum a čas konání",
        blank=True,
        null=True,
    )  # If undefined, assume this event was in the past

    class TypeChoices(models.TextChoices):
        RECOMMENDED = "recommended", "Doporučené"
        OPTIONAL = "optional", "Volitelné"

    groups = models.ManyToManyField(
        LectureGroup,
        blank=True,
        related_name="lectures",
        verbose_name="Výukové skupiny",
    )

    type = models.CharField(
        choices=TypeChoices.choices,
        max_length=11,
        verbose_name="Typ",
    )

    name = models.CharField(
        max_length=128,
        verbose_name="Název",
    )

    description = MarkdownxField(
        blank=True,
        null=True,
        verbose_name="Popis",
        help_text="Můžeš použít Markdown.",
    )

    @property
    def is_current(self) -> bool:
        # On or after the current time, minus 8 hours
        return self.timestamp >= (timezone.now() - self.is_current_treshold)

    class Meta:
        verbose_name = "Lekce"
        verbose_name_plural = verbose_name
        ordering = ("-timestamp", "-name")


class LectureLector(NameStrMixin, models.Model):
    lecture = models.ForeignKey(
        "Lecture",
        on_delete=models.CASCADE,
        related_name="lectors",
        verbose_name="Lekce",
    )

    name = models.CharField(
        max_length=128,
        verbose_name="Jméno",
    )

    link = models.URLField(
        max_length=256,
        blank=True,
        null=True,
        verbose_name="Odkaz",
    )

    class Meta:
        verbose_name = "Lektor"
        verbose_name_plural = "Lektoři"


class LectureRecording(NameStrMixin, models.Model):
    lecture = models.ForeignKey(
        "Lecture",
        on_delete=models.CASCADE,
        related_name="recordings",
        verbose_name="Lekce",
    )

    name = models.CharField(
        max_length=128,
        verbose_name="Název",
    )

    link = models.URLField(
        max_length=256,
        blank=True,
        null=True,
        verbose_name="Odkaz",
    )

    class Meta:
        verbose_name = "Nahrávka"
        verbose_name_plural = "Nahrávky"


class LectureMaterial(NameStrMixin, models.Model):
    lecture = models.ForeignKey(
        "Lecture",
        on_delete=models.CASCADE,
        related_name="materials",
        verbose_name="Lekce",
    )

    name = models.CharField(
        max_length=128,
        verbose_name="Název",
    )

    link = models.URLField(
        max_length=256,
        blank=True,
        null=True,
        verbose_name="Odkaz",
        help_text="Pokud máš zadaný odkaz, nemůžeš definovat soubor.",
    )

    file = models.FileField(
        blank=True,
        null=True,
        verbose_name="Soubor",
        help_text="Pokud máš vložený soubor, nemůžeš definovat odkaz.",
    )

    def clean(self) -> None:
        BOTH_FILE_AND_LINK_DEFINED_ERROR = (
            "Definuj prosím pouze odkaz, nebo soubor. Nemůžeš mít oboje najednou."
        )

        if self.file and self.link:
            raise ValidationError(
                {
                    "link": BOTH_FILE_AND_LINK_DEFINED_ERROR,
                    "file": BOTH_FILE_AND_LINK_DEFINED_ERROR,
                }
            )

    class Meta:
        verbose_name = "Materiál"
        verbose_name_plural = "Materiály"