from django import forms
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import PasswordChangeForm as DjangoPasswordChangeForm
from django.contrib.auth.forms import PasswordResetForm as DjangoPasswordResetForm
from django.utils.translation import gettext_lazy


class LoginForm(AuthenticationForm):
    username = forms.CharField(max_length=254, widget=forms.TextInput())

    password = forms.CharField(
        widget=forms.PasswordInput(
            attrs={
                "placeholder": gettext_lazy("Enter password"),
            }
        ),
        strip=False,
    )

    remember = forms.BooleanField(required=False)

    error_messages = {
        **AuthenticationForm.error_messages,
        "invalid_login": gettext_lazy(
            "Your %(username_field)s and password didn't match. Please try again."
        ),
    }

    def __init__(self, request=None, *args, **kwargs):
        super().__init__(request=request, *args, **kwargs)
        self.fields["username"].widget.attrs["placeholder"] = gettext_lazy(
            "Enter your %(username_field_name)s"
        ) % {"username_field_name": self.username_field.verbose_name}
        self.fields["username"].widget.attrs["autofocus"] = ""

    @property
    def extra_fields(self):
        for field_name in self.fields.keys():
            if field_name not in ["username", "password", "remember"]:
                yield field_name, self[field_name]

    def get_invalid_login_error(self):
        return forms.ValidationError(
            self.error_messages["invalid_login"],
            code="invalid_login",
            params={"username_field": self.username_field.verbose_name},
        )


class PasswordResetForm(DjangoPasswordResetForm):
    email = forms.EmailField(
        label=gettext_lazy("Enter your email address to reset your password"),
        max_length=254,
        required=True,
    )

    @property
    def extra_fields(self):
        for field_name in self.fields.keys():
            if field_name not in ["email"]:
                yield field_name, self[field_name]


class PasswordChangeForm(DjangoPasswordChangeForm):
    """
    Since this is displayed as part of a larger form, this differs from the vanilla Django
    PasswordChangeForm as follows:
    * the old-password field is not auto-focused
    * Fields are not marked as required
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        try:
            del self.fields["old_password"].widget.attrs["autofocus"]
        except KeyError:
            pass

        self.fields["old_password"].required = False
        self.fields["new_password1"].required = False
        self.fields["new_password2"].required = False
