from django import forms
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError

from kaehmy.models import PresetRole, CustomRole, Application, Comment, BaseRole


class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
    option_template_name = "checkbox_option.html"

    def create_option(
        self, name, formIterator, label, selected, index, subindex=None, attrs=None
    ):
        dic = super(CheckboxSelectMultiple, self).create_option(
            name, formIterator, label, selected, index, subindex, attrs
        )
        description = PresetRole.objects.get(id=formIterator.value).description
        dic["description"] = description
        return dic

    def __init__(self, *args, **kwargs):
        super(CheckboxSelectMultiple, self).__init__(*args, **kwargs)


class ApplicationForm(forms.ModelForm):
    """Class representing Kaehmy form."""

    class Meta:
        """Meta for class Application."""

        model = Application
        fields = [
            "name",
            "email",
            "phone_number",
            "year",
            "preset_roles",
            "custom_roles",
            "custom_role_name",
            "custom_role_is_board",
            "text",
        ]

    def __init__(self, *args, **kwargs):
        super(ApplicationForm, self).__init__(*args, **kwargs)

        self.fields["email"].label = _("Email (not public)")
        self.fields["phone_number"].label = _("Phone number (not public)")

        custom_roles_exist = CustomRole.objects.all().exists()
        self.fields["custom_roles"].widget = (
            forms.widgets.CheckboxSelectMultiple()
            if custom_roles_exist
            else forms.HiddenInput()
        )
        self.fields["custom_roles"].help_text = ""
        self.fields["custom_roles"].label = _("Custom roles")
        self.fields["custom_roles"].queryset = CustomRole.objects.all()

        for cat_id, category in BaseRole.CATEGORIES:
            key = "preset_roles_{}".format(cat_id)
            qset = PresetRole.objects.filter(category=cat_id).order_by(
                "category", "-is_board"
            )
            self.fields[key] = forms.ModelMultipleChoiceField(qset)
            self.fields[key].widget = CheckboxSelectMultiple(
                attrs={
                    "title": _("Preset roles"),
                    "name": "preset_roles",
                }
            )
            self.fields[key].help_text = ""
            self.fields[key].queryset = qset
            self.fields[key].label = _(category)
            self.fields[key].required = False

    def clean(self):
        cleaned_data = super(ApplicationForm, self).clean()
        for key in cleaned_data.keys():
            if "preset_roles_" in key:
                cleaned_data["preset_roles"] = (
                    cleaned_data["preset_roles"] | cleaned_data[key]
                )

        return cleaned_data

    def clean_phone_number(self):
        """Clean phone number field."""
        number = self.cleaned_data.get("phone_number")
        if number.isdigit():
            return number
        else:
            raise ValidationError(_("Invalid phone number"))

    def clean_custom_role_name(self):
        """Check that no other custom role with same name exists."""
        custom_name = self.cleaned_data.get("custom_role_name")
        if not CustomRole.objects.filter(name=custom_name).exists():
            return custom_name
        else:
            raise ValidationError(_("Custom role with the same name already exists."))

    def non_role_fields(self):
        return [
            self.fields[k]
            for k in self.fields.keys()
            if k not in ["preset_roles", "custom_roles"]
        ]


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ["name", "email", "message", "parent"]
