from django import forms
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext_lazy

from pretalx.common.forms.widgets import MarkdownWidget
from pretalx.common.mixins.forms import ReadOnlyFlag
from pretalx.common.phrases import phrases
from pretalx.submission.models import Review


class ReviewForm(ReadOnlyFlag, forms.ModelForm):
    def __init__(self, event, user, *args, instance=None, **kwargs):
        self.event = event
        remaining_votes = user.remaining_override_votes(event)
        self.may_override = event.settings.allow_override_votes and remaining_votes
        self.may_override = self.may_override or (
            instance and instance.override_vote is not None
        )
        self.min_value = int(event.settings.review_min_score)
        self.max_value = int(event.settings.review_max_score)
        if instance:
            if instance.override_vote is True:
                instance.score = self.max_value + 1
            elif instance.override_vote is False:
                instance.score = self.min_value - 1

        super().__init__(*args, instance=instance, **kwargs)
        choices = (
            [(None, _("No score"))] if not event.settings.review_score_mandatory else []
        )
        for counter in range(abs(self.max_value - self.min_value) + 1):
            value = self.min_value + counter
            name = event.settings.get(f"review_score_name_{value}")
            name = f"{value} (“{name}”)" if name else value
            choices.append((value, name))
        if self.may_override:
            choices.insert(1, (self.min_value - 1, _("Negative override (Veto)")))
            choices.append((self.max_value + 1, _("Positive override")))

        self.fields["score"] = forms.ChoiceField(
            choices=choices,
            required=event.settings.review_score_mandatory,
            widget=forms.RadioSelect,
            disabled=kwargs.get("read_only", False),
            help_text=ngettext_lazy(
                "You have {count} override vote left.",
                "You have {count} override votes left.",
                remaining_votes,
            ).format(count=remaining_votes)
            if remaining_votes
            else "",
        )
        self.fields["text"].widget.attrs["rows"] = 2
        self.fields["text"].widget.attrs["placeholder"] = phrases.orga.example_review
        self.fields["text"].required = event.settings.review_text_mandatory
        self.fields["text"].help_text += " " + phrases.base.use_markdown

    def clean_score(self):
        score = self.cleaned_data.get("score")
        score = int(score) if score else None
        if score and not self.min_value <= score <= self.max_value:
            if not (
                score in (self.min_value - 1, self.max_value + 1) and self.may_override
            ):
                raise forms.ValidationError(
                    _(
                        f"Please assign a score between {self.min_value} and {self.max_value}!"
                    )
                )
        return score

    def clean(self):
        cleaned_data = super().clean()
        score = cleaned_data.get("score")
        if score == self.min_value - 1:
            cleaned_data["score"] = None
            if self.may_override:
                self.instance.override_vote = False
        elif score == self.max_value + 1:
            cleaned_data["score"] = None
            if self.may_override:
                self.instance.override_vote = True
        else:
            self.instance.override_vote = None
        if self.instance.id:
            self.instance.save()

    class Meta:
        model = Review
        fields = ("text", "score")
        widgets = {
            "text": MarkdownWidget,
        }
