from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _

# #############################################################################
#  Models regarding an election
# #############################################################################


class Election(models.Model):
    name = models.CharField(_("nom"), max_length=255)
    short_name = models.SlugField(_("nom bref"), unique=True)
    description = models.TextField(_("description"), blank=True)

    start_date = models.DateTimeField(_("date et heure de début"))
    end_date = models.DateTimeField(_("date et heure de fin"))

    restricted = models.BooleanField(
        _("restreint le vote à une liste de personnes"), default=True
    )

    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name="elections_created",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )

    results_public = models.BooleanField(_("résultats publics"), default=False)
    tallied = models.BooleanField(_("dépouillée"), default=False)
    # TODO : cache tally or recompute it each time ?

    archived = models.BooleanField(_("archivée"), default=False)

    @property
    def preferred_method(self):
        if self.restricted:
            return "PWD"
        return "CAS"

    class Meta:
        ordering = ["-start_date", "-end_date"]


class Question(models.Model):
    election = models.ForeignKey(
        Election, related_name="questions", on_delete=models.CASCADE
    )
    text = models.TextField(_("question"), blank=False)
    # We cache the maximum number of votes for an option
    max_votes = models.PositiveSmallIntegerField(
        _("nombre maximal de votes reçus"), default=0
    )

    class Meta:
        ordering = ["id"]


class Option(models.Model):
    question = models.ForeignKey(
        Question, related_name="options", on_delete=models.CASCADE
    )
    text = models.TextField(_("texte"), blank=False)
    voters = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name="votes",
    )
    # For now, we store the amount of votes received after the election is tallied
    nb_votes = models.PositiveSmallIntegerField(_("nombre de votes reçus"), default=0)

    class Meta:
        ordering = ["id"]


# #############################################################################
#  Modification of the base User Model
# #############################################################################


class User(AbstractUser):
    election = models.ForeignKey(
        Election,
        related_name="registered_voters",
        null=True,
        blank=True,
        on_delete=models.CASCADE,
    )

    @property
    def base_username(self):
        return self.username.split("__")[-1]

    def can_vote(self, election):
        # Si c'est un·e utilisateur·ice CAS, iel peut voter dans les élections
        # ouvertes à tou·te·s
        if self.election is None:
            return not election.restricted
        # Pour les élections restreintes, il faut y être associé
        return election.restricted and (self.election == election)

    def connection_method(self):
        if self.election is None:
            return _("CAS")
        return _("identifiants spécifiques")
