from datetime import timedelta
from math import ceil

from django.conf import settings
from django.db import models
from django.utils import timezone

from ...plugins.models import PluginDataModel


class Poll(PluginDataModel):
    category = models.ForeignKey("misago_categories.Category", on_delete=models.CASCADE)
    thread = models.OneToOneField("misago_threads.Thread", on_delete=models.CASCADE)
    poster = models.ForeignKey(
        settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL
    )
    poster_name = models.CharField(max_length=255)
    poster_slug = models.CharField(max_length=255)

    posted_on = models.DateTimeField(default=timezone.now)
    length = models.PositiveIntegerField(default=0)

    question = models.CharField(max_length=255)
    choices = models.JSONField()
    allowed_choices = models.PositiveIntegerField(default=1)
    allow_revotes = models.BooleanField(default=False)

    votes = models.PositiveIntegerField(default=0)
    is_public = models.BooleanField(default=False)

    def move(self, thread):
        if self.thread_id != thread.id:
            self.thread = thread
            self.category_id = thread.category_id
            self.save()

            self.pollvote_set.update(thread=self.thread, category_id=self.category_id)

    @property
    def ends_on(self):
        if self.length:
            return self.posted_on + timedelta(days=self.length)

    @property
    def is_over(self):
        if self.length:
            return timezone.now() > self.ends_on
        return False

    @property
    def thread_type(self):
        return self.category.thread_type

    def get_api_url(self):
        return self.thread_type.get_poll_api_url(self)

    def get_votes_api_url(self):
        return self.thread_type.get_poll_votes_api_url(self)

    def make_choices_votes_aware(self, user):
        if user.is_anonymous:
            for choice in self.choices:
                choice["selected"] = False
            return

        queryset = self.pollvote_set.filter(voter=user).values("choice_hash")
        user_votes = [v["choice_hash"] for v in queryset]

        for choice in self.choices:
            choice["selected"] = choice["hash"] in user_votes

    @property
    def has_selected_choices(self):
        for choice in self.choices:
            if choice.get("selected"):
                return True
        return False

    @property
    def view_choices(self):
        view_choices = []
        for choice in self.choices:
            if choice["votes"] and self.votes:
                proc = int(ceil(choice["votes"] * 100 / self.votes))
            else:
                proc = 0

            view_choices.append(
                {
                    "label": choice["label"],
                    "votes": choice["votes"],
                    "selected": choice["selected"],
                    "proc": proc,
                }
            )
        return view_choices
