from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.auth.password_validation import validate_password

from . import roles
from .services import actor_is_admin, user_role

User = get_user_model()


class UserForm(forms.ModelForm):
    role = forms.ChoiceField(label="الدور")
    password1 = forms.CharField(label="كلمة المرور", widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}), required=False)
    password2 = forms.CharField(label="تأكيد كلمة المرور", widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}), required=False)

    class Meta:
        model = User
        fields = ("username", "first_name", "last_name", "email", "is_active")
        labels = {"username": "اسم المستخدم", "first_name": "الاسم الأول", "last_name": "اسم العائلة",
                  "email": "البريد الإلكتروني", "is_active": "الحساب مفعّل"}

    def __init__(self, *args, actor, **kwargs):
        super().__init__(*args, **kwargs)
        self.actor = actor
        allowed = list(roles.ROLE_LABELS) if actor_is_admin(actor) else [roles.ACCOUNTANT, roles.CUSTOMER_SERVICE]
        self.fields["role"].choices = [(r, roles.ROLE_LABELS[r]) for r in allowed]
        self.fields["email"].required = True
        if self.instance.pk:
            self.fields["role"].initial = user_role(self.instance)
            self.fields["password1"].help_text = "اتركها فارغة للإبقاء على كلمة المرور الحالية."
        else:
            self.fields["password1"].required = self.fields["password2"].required = True

    def clean_is_active(self):
        active = self.cleaned_data["is_active"]
        if self.instance.pk and self.instance.pk == self.actor.pk and not active:
            raise forms.ValidationError("لا يمكنك تعطيل حسابك بنفسك.")
        return active

    def clean_role(self):
        role = self.cleaned_data["role"]
        if self.instance.pk and self.instance.pk == self.actor.pk and role != user_role(self.instance):
            raise forms.ValidationError("لا يمكنك تغيير دورك بنفسك.")
        return role

    def clean(self):
        data = super().clean()
        p1, p2 = data.get("password1"), data.get("password2")
        if p1 or p2:
            if p1 != p2:
                self.add_error("password2", "كلمتا المرور غير متطابقتين.")
            else:
                probe = self.instance if self.instance.pk else User(username=data.get("username", ""), email=data.get("email", ""))
                try:
                    validate_password(p1, probe)
                except forms.ValidationError as exc:
                    self.add_error("password1", exc)
        return data

    def save(self, commit=True):
        user = super().save(commit=False)
        if self.cleaned_data.get("password1"):
            user.set_password(self.cleaned_data["password1"])
        user.save()
        group = Group.objects.get(name=self.cleaned_data["role"])
        user.groups.set([group])
        return user
