""" Model definitions for the quiz """

from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models


class CriterionRating(models.Model):
    """
    This is the relation between Sport and Criterion.
    You can use it to add a rating for a specific criterion to a sport.
    To see it's usage check Sport.rate() and Sport.get_rating()
    """

    rating = models.IntegerField(
        validators=[MaxValueValidator(10), MinValueValidator(1)]
    )
    criterion = models.ForeignKey("Criterion", on_delete=models.CASCADE)
    sport = models.ForeignKey("Sport", on_delete=models.CASCADE)

    def __str__(self):
        return str(self.sport) + " - " + str(self.criterion) + ": " + str(self.rating)


class Sport(models.Model):
    """
    Defines a Sport with name, url that leads to the booking page.
    A sport includes ratings for all criterions.
    (e.g. How much it corresponds to the criterion "Martial Arts")
    """

    name = models.TextField()
    url = models.URLField()
    criteria_ratings = models.ManyToManyField("Criterion", through="CriterionRating")

    def __str__(self):
        return self.name

    def rate(self, criterion, rating):
        """Defines how much (rating) the sport meets the given criterion"""
        rating_obj, _ = CriterionRating.objects.get_or_create(
            sport=self, criterion=criterion, defaults={"rating": rating}
        )
        rating_obj.rating = rating
        rating_obj.save()
        return rating_obj

    def get_rating(self, criterion):
        """Returns how much the sport meets the given criterion"""
        criterion_rating = CriterionRating.objects.get(sport=self, criterion=criterion)
        return criterion_rating.rating


class Criterion(models.Model):
    """
    Defines a Sport property that is used a a criterion for our quiz.
    (e.g. Individual or Team sport)
    """

    name = models.TextField()

    def __str__(self):
        return self.name


class CallToMove(models.Model):
    """Defines text and image that are used to show a call to move between questions"""

    text = models.TextField()
    image = models.ImageField(null=True, max_length=200)

    def __str__(self):
        return self.text


class KnowledgeSnack(models.Model):
    """Defines text and image that are used to show a KnowledgeSnack between questions"""

    text = models.TextField()
    image = models.ImageField(null=True, max_length=200)

    def __str__(self):
        return self.text


class Question(models.Model):
    """Defines a Question that is assigned to exactly one Criterion"""

    text = models.TextField()
    criterion = models.OneToOneField(
        Criterion, on_delete=models.CASCADE, primary_key=True
    )

    def __str__(self):
        return self.text