from django import forms
from django.core.exceptions import PermissionDenied

from ..models.auth import OTPSession


class OTPForm(forms.Form):
    otp = forms.IntegerField(widget=forms.TextInput(attrs={"autofocus": True}))

    error_messages = {
        "invalid_otp": (
            "The one-time password you entered was incorrect. Please try again."
        ),
        "session_expired": "Your session has expired, please try again."
    }

    def __init__(self, request=None, *args, **kwargs):
        self.request = request
        self.user_cache = None
        super().__init__(*args, **kwargs)

        # Set the max length and label for the "username" field.
        otp_max_length = 8
        self.fields["otp"].max_length = otp_max_length
        self.fields["otp"].widget.attrs["maxlength"] = otp_max_length

        if self.fields["otp"].label is None:
            self.fields["otp"].label = "One-Time Password"

    def clean(self):
        otp = self.cleaned_data.get("otp")
        session = self.get_session()

        if not session.is_alive():
            raise PermissionDenied(self.error_messages["session_expired"])

        if otp is None or not session.validate_token(otp):
            raise self.get_invalid_otp_error()

        return self.cleaned_data

    def get_session(self):
        return OTPSession.objects.get(uuid=self.request.session["OTPSession"])

    def get_invalid_otp_error(self):
        return ValidationError(
            self.error_messages["invalid_otp"],
            code="invalid_otp",
            params={"otp": "One-Time Password"},
        )