from django.db import models
from django.urls import reverse
from django.core.exceptions import ValidationError
from autoslug import AutoSlugField
from website.validators import MaxFileSizeValidator
from comments.models import AbstractComment


class Category(models.Model):
    name = models.CharField(max_length=256, verbose_name="nom", unique=True)
    slug = AutoSlugField(populate_from="name", unique=True)

    class Meta:
        ordering = ["name"]
        verbose_name = "catégorie"

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("inventory:category", args=(self.slug,))


class Tag(models.Model):
    name = models.CharField(max_length=256, verbose_name="nom", unique=True)
    slug = AutoSlugField(populate_from="name", unique=True)

    class Meta:
        ordering = ["name"]

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse("inventory:tag", args=(self.slug,))


class Game(models.Model):
    title = models.CharField(verbose_name="titre du jeu", max_length=256, unique=True)
    slug = AutoSlugField(populate_from="title", unique=True)

    nb_player_min = models.PositiveSmallIntegerField(
        verbose_name="nombre de joueur·se·s minimum"
    )
    nb_player_max = models.PositiveSmallIntegerField(
        verbose_name="nombre de joueur·se·s maximum"
    )
    player_range = models.CharField(
        max_length=256,
        blank=True,
        help_text="Affichage personnalisé pour le nombre de joueur·se·s",
        verbose_name="nombre de joueur·se·s",
    )
    duration = models.CharField(
        max_length=256, blank=True, verbose_name="durée de partie"
    )

    game_designer = models.CharField(
        max_length=256, blank=True, verbose_name="game designer"
    )
    illustrator = models.CharField(
        max_length=256, blank=True, verbose_name="illustrateur·trice"
    )
    editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur")

    category = models.ForeignKey(
        Category, on_delete=models.RESTRICT, verbose_name="catégorie"
    )
    tags = models.ManyToManyField(Tag, blank=True, verbose_name="tags")

    description = models.TextField(blank=True, verbose_name="description")
    image = models.ImageField(
        upload_to="game_img/",
        blank=True,
        verbose_name="image",
        help_text="L'image doit peser 512 Kio au maximum",
        validators=[MaxFileSizeValidator(512)],
    )

    missing_elements = models.TextField(blank=True, verbose_name="pièces manquantes")

    class Meta:
        ordering = ["title"]
        verbose_name = "jeu"
        verbose_name_plural = "jeux"

    def __str__(self):
        return self.title

    def clean(self):
        if self.nb_player_min > self.nb_player_max:
            raise ValidationError(
                {
                    "nb_player_max": "Le nombre de joueur·se·s maximum doit être supérieur au nombre de joueur·se·s minimum"
                }
            )

    def get_player_range(self):
        if self.player_range:
            return self.player_range
        elif self.nb_player_min != self.nb_player_max:
            return "{} à {} joueur·se·s".format(self.nb_player_min, self.nb_player_max)
        else:
            return "{} joueur·se·s".format(self.nb_player_min)

    def get_absolute_url(self):
        return reverse("inventory:game", args=(self.slug,))


class GameComment(AbstractComment):
    commented_object = models.ForeignKey(
        Game, on_delete=models.CASCADE, related_name="comments", verbose_name="jeu"
    )

    class Meta:
        ordering = ["created_on"]
        verbose_name = "commentaire sur un jeu"
        verbose_name_plural = "commentaires sur des jeux"

    def get_modification_url(self):
        return reverse(
            "inventory:modify_game_comment", args=(self.commented_object.slug, self.id)
        )
