"""Django forms for ECP Auth.

Provides forms for certificate upload during login and registration.
"""

from __future__ import annotations

import logging
from typing import Any

from django import forms
from django.core.exceptions import ValidationError

logger: logging.Logger = logging.getLogger(__name__)


class CertificateUploadForm(forms.Form):
    """Form for uploading a PKCS#12 certificate file for login.

    Fields:
        pkcs12_file: The PKCS#12 (.p12/.pfx) file containing the
            user's private key and certificate.
        pkcs12_password: Password to decrypt the PKCS#12 file.
    """

    pkcs12_file = forms.FileField(
        label="Certificate File (.p12 / .pfx)",
        help_text="Upload your PKCS#12 certificate file.",
        widget=forms.ClearableFileInput(
            attrs={
                "accept": ".p12,.pfx",
                "class": "form-control",
                "id": "id_pkcs12_file",
            }
        ),
    )

    pkcs12_password = forms.CharField(
        label="Certificate Password",
        widget=forms.PasswordInput(
            attrs={
                "class": "form-control",
                "placeholder": "Enter certificate password",
                "id": "id_pkcs12_password",
                "autocomplete": "off",
            }
        ),
        required=False,
        help_text="Password for the PKCS#12 file (leave blank if none).",
    )

    def clean_pkcs12_file(self) -> Any:
        """Validate the uploaded PKCS#12 file.

        Returns:
            The validated uploaded file.

        Raises:
            ValidationError: If the file is too large or has an invalid extension.
        """
        uploaded_file = self.cleaned_data.get("pkcs12_file")

        if uploaded_file is None:
            raise ValidationError("Please upload a certificate file.")

        # Check file size (max 5 MB)
        max_size: int = 5 * 1024 * 1024
        if uploaded_file.size > max_size:
            raise ValidationError(
                f"Certificate file is too large. "
                f"Maximum size: {max_size // (1024 * 1024)} MB."
            )

        # Check file extension
        name: str = uploaded_file.name.lower()
        if not name.endswith((".p12", ".pfx")):
            raise ValidationError(
                "Invalid file format. Please upload a .p12 or .pfx file."
            )

        return uploaded_file


class RegisterForm(forms.Form):
    """Form for user registration with ECP certificate.

    Fields:
        username: Desired username for the new account.
        email: Email address (optional).
        pkcs12_file: The PKCS#12 file for certificate registration.
        pkcs12_password: Password for the PKCS#12 file.
    """

    username = forms.CharField(
        max_length=150,
        label="Username",
        widget=forms.TextInput(
            attrs={
                "class": "form-control",
                "placeholder": "Enter username",
                "id": "id_username",
                "autocomplete": "username",
            }
        ),
        help_text="Choose a unique username.",
    )

    email = forms.EmailField(
        label="Email Address",
        required=False,
        widget=forms.EmailInput(
            attrs={
                "class": "form-control",
                "placeholder": "Enter email address (optional)",
                "id": "id_email",
                "autocomplete": "email",
            }
        ),
    )

    pkcs12_file = forms.FileField(
        label="Certificate File (.p12 / .pfx)",
        help_text="Upload your PKCS#12 certificate file.",
        widget=forms.ClearableFileInput(
            attrs={
                "accept": ".p12,.pfx",
                "class": "form-control",
                "id": "id_register_pkcs12_file",
            }
        ),
    )

    pkcs12_password = forms.CharField(
        label="Certificate Password",
        widget=forms.PasswordInput(
            attrs={
                "class": "form-control",
                "placeholder": "Enter certificate password",
                "id": "id_register_pkcs12_password",
                "autocomplete": "off",
            }
        ),
        required=False,
        help_text="Password for the PKCS#12 file (leave blank if none).",
    )

    def clean_username(self) -> str:
        """Validate that the username is unique.

        Returns:
            The validated username.

        Raises:
            ValidationError: If the username is already taken.
        """
        from django.contrib.auth import get_user_model

        User = get_user_model()
        username: str = self.cleaned_data["username"]

        if User.objects.filter(username=username).exists():
            raise ValidationError(
                "This username is already taken. Please choose another."
            )

        return username

    def clean_pkcs12_file(self) -> Any:
        """Validate the uploaded PKCS#12 file.

        Returns:
            The validated uploaded file.

        Raises:
            ValidationError: If the file is invalid.
        """
        uploaded_file = self.cleaned_data.get("pkcs12_file")

        if uploaded_file is None:
            raise ValidationError("Please upload a certificate file.")

        max_size: int = 5 * 1024 * 1024
        if uploaded_file.size > max_size:
            raise ValidationError(
                f"Certificate file is too large. "
                f"Maximum size: {max_size // (1024 * 1024)} MB."
            )

        name: str = uploaded_file.name.lower()
        if not name.endswith((".p12", ".pfx")):
            raise ValidationError(
                "Invalid file format. Please upload a .p12 or .pfx file."
            )

        return uploaded_file
