from django.db import models
from django.urls import reverse
from django.core.validators import MinValueValidator
from django.core.exceptions import ValidationError
from autoslug import AutoSlugField
from website.validators import MaxFileSizeValidator
from accounts.models import User
from inventory.models import Category, Tag
from comments.models import AbstractComment


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

    price = models.DecimalField(
        max_digits=6,
        decimal_places=2,
        verbose_name="prix en euros",
        validators=[MinValueValidator(0)],
    )
    buy_link = models.URLField(verbose_name="lien vers un site d'achat")

    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_precisions = models.CharField(
        max_length=256,
        blank=True,
        verbose_name="précisions sur le nombre de joueur·se·s",
        help_text="Pour indiquer une éventuelle contrainte (ex. parité) ou information sur le nombre de joueur·se·s",
    )

    duration = models.CharField(max_length=256, 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.SET_NULL,
        blank=True,
        null=True,
        verbose_name="catégorie",
        help_text="Idée de catégorie dans laquelle ranger ce jeu",
    )
    tags = models.ManyToManyField(
        Tag,
        blank=True,
        verbose_name="tags qui correspondent à ce jeu",
        help_text="Vous pouvez en sélectionner plusieurs ou aucun (sur ordinateur Ctrl+Clic change l'état de selection d'un tag)",
    )

    description = models.TextField(
        blank=True,
        verbose_name="description",
        help_text="Peut correspondre à celle de l'éditeur et ne doit pas contenir d'avis personnel",
    )

    image = models.ImageField(
        upload_to="suggestion_img/",
        blank=True,
        verbose_name="image",
        help_text="Image du jeu de moins de 512 Kio à téléverser (par exemple une photo de sa boite)",
        validators=[MaxFileSizeValidator(512)],
    )

    upvoting_users = models.ManyToManyField(
        User,
        blank=True,
        related_name="upvoted_suggestions",
        verbose_name="personnes intéressées",
    )

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

    def __str__(self):
        return self.title

    def clean(self):
        if not self.nb_player_min or not self.nb_player_max:
            return
        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):
        precisions = ""
        if self.player_range_precisions:
            precisions = " ({})".format(self.player_range_precisions)
        if self.nb_player_min != self.nb_player_max:
            return "{} à {} joueur·se·s{}".format(
                self.nb_player_min, self.nb_player_max, precisions
            )
        else:
            return "{} joueur·se·s{}".format(self.nb_player_min, precisions)

    def get_absolute_url(self):
        return reverse("suggestions:suggestion", args=(self.slug,))


class SuggestionComment(AbstractComment):
    commented_object = models.ForeignKey(
        Suggestion,
        on_delete=models.CASCADE,
        related_name="comments",
        verbose_name="suggestion",
    )

    class Meta:
        ordering = ["created_on"]
        verbose_name = "commentaire sur une suggestion"
        verbose_name_plural = "commentaires sur des suggestions"

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