# -*- coding: utf-8 -*-
"""
Accounts Forms

This module contains all forms for the accounts application,
including authentication forms, user management forms, and
role/permission management forms.

Forms included:
- Authentication forms (login, password reset, password change)
- User profile and management forms
- Role and permission management forms
- API key and security forms

Author: Adtlas Development Team
Version: 1.0.0
Created: 2024
"""

import re
from typing import Dict, Any, Optional, List

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm as BasePasswordChangeForm
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.core.validators import RegexValidator
from django.conf import settings

from .models import (
    UserProfile, Role, Permission, UserRole, RolePermission,
    APIKey, UserAccess, PermissionGroup
)
from .validators import (
    validate_password_strength, validate_phone_number,
    validate_timezone, validate_language_code
)


# ============================================================================
# Authentication Forms
# ============================================================================

class LoginForm(forms.Form):
    """
    Enhanced login form with additional security features.
    
    This form handles user authentication with features like
    remember me functionality and input validation.
    
    Fields:
        username (CharField): Username or email address
        password (CharField): User password
        remember_me (BooleanField): Remember login session
    """
    
    username = forms.CharField(
        max_length=150,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': _('Username or Email'),
            'autocomplete': 'username',
            'autofocus': True,
        }),
        label=_('Username or Email'),
        help_text=_('Enter your username or email address')
    )
    
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': _('Password'),
            'autocomplete': 'current-password',
        }),
        label=_('Password'),
        help_text=_('Enter your password')
    )
    
    remember_me = forms.BooleanField(
        required=False,
        widget=forms.CheckboxInput(attrs={
            'class': 'form-check-input',
        }),
        label=_('Remember me'),
        help_text=_('Keep me logged in for 30 days')
    )
    
    def clean_username(self) -> str:
        """
        Clean and validate username field.
        
        Returns:
            str: Cleaned username
        
        Raises:
            ValidationError: If username is invalid
        """
        username = self.cleaned_data.get('username', '').strip().lower()
        
        if not username:
            raise ValidationError(_('Username is required.'))
        
        # Check if it's an email or username
        if '@' in username:
            # Validate email format
            try:
                forms.EmailField().clean(username)
            except ValidationError:
                raise ValidationError(_('Please enter a valid email address.'))
        else:
            # Validate username format
            if not re.match(r'^[a-zA-Z0-9_]+$', username):
                raise ValidationError(_('Username can only contain letters, numbers, and underscores.'))
        
        return username
    
    def clean_password(self) -> str:
        """
        Clean and validate password field.
        
        Returns:
            str: Cleaned password
        
        Raises:
            ValidationError: If password is invalid
        """
        password = self.cleaned_data.get('password', '')
        
        if not password:
            raise ValidationError(_('Password is required.'))
        
        if len(password) < 8:
            raise ValidationError(_('Password must be at least 8 characters long.'))
        
        return password


class PasswordResetForm(forms.Form):
    """
    Password reset request form.
    
    This form handles password reset requests by email.
    
    Fields:
        email (EmailField): User's email address
    """
    
    email = forms.EmailField(
        max_length=254,
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': _('Email Address'),
            'autocomplete': 'email',
            'autofocus': True,
        }),
        label=_('Email Address'),
        help_text=_('Enter the email address associated with your account')
    )
    
    def clean_email(self) -> str:
        """
        Clean and validate email field.
        
        Returns:
            str: Cleaned email address
        
        Raises:
            ValidationError: If email is invalid
        """
        email = self.cleaned_data.get('email', '').strip().lower()
        
        if not email:
            raise ValidationError(_('Email address is required.'))
        
        return email


class PasswordChangeForm(BasePasswordChangeForm):
    """
    Enhanced password change form with strength validation.
    
    This form extends Django's built-in password change form
    with additional password strength validation.
    """
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with custom widget attributes.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Customize widget attributes
        self.fields['old_password'].widget.attrs.update({
            'class': 'form-control',
            'placeholder': _('Current Password'),
            'autocomplete': 'current-password',
        })
        
        self.fields['new_password1'].widget.attrs.update({
            'class': 'form-control',
            'placeholder': _('New Password'),
            'autocomplete': 'new-password',
        })
        
        self.fields['new_password2'].widget.attrs.update({
            'class': 'form-control',
            'placeholder': _('Confirm New Password'),
            'autocomplete': 'new-password',
        })
        
        # Update help texts
        self.fields['new_password1'].help_text = _(
            'Password must be at least 8 characters long and contain '
            'uppercase, lowercase, numbers, and special characters.'
        )
    
    def clean_new_password1(self) -> str:
        """
        Validate new password strength.
        
        Returns:
            str: Validated new password
        
        Raises:
            ValidationError: If password doesn't meet strength requirements
        """
        password = self.cleaned_data.get('new_password1')
        
        if password:
            # Use custom password strength validator
            validate_password_strength(password)
        
        return password


class SetPasswordForm(forms.Form):
    """
    Set password form for password reset confirmation.
    
    This form is used when users reset their password via email link.
    
    Fields:
        new_password1 (CharField): New password
        new_password2 (CharField): Password confirmation
    """
    
    new_password1 = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': _('New Password'),
            'autocomplete': 'new-password',
        }),
        label=_('New Password'),
        help_text=_(
            'Password must be at least 8 characters long and contain '
            'uppercase, lowercase, numbers, and special characters.'
        )
    )
    
    new_password2 = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': _('Confirm New Password'),
            'autocomplete': 'new-password',
        }),
        label=_('Confirm New Password'),
        help_text=_('Enter the same password as before, for verification.')
    )
    
    def clean_new_password1(self) -> str:
        """
        Validate new password strength.
        
        Returns:
            str: Validated new password
        
        Raises:
            ValidationError: If password doesn't meet strength requirements
        """
        password = self.cleaned_data.get('new_password1')
        
        if password:
            validate_password_strength(password)
        
        return password
    
    def clean_new_password2(self) -> str:
        """
        Validate password confirmation.
        
        Returns:
            str: Validated password confirmation
        
        Raises:
            ValidationError: If passwords don't match
        """
        password1 = self.cleaned_data.get('new_password1')
        password2 = self.cleaned_data.get('new_password2')
        
        if password1 and password2 and password1 != password2:
            raise ValidationError(_('The two password fields didn\'t match.'))
        
        return password2


# ============================================================================
# User Management Forms
# ============================================================================

class UserProfileForm(forms.ModelForm):
    """
    User profile form for editing user information.
    
    This form handles user profile updates including personal information,
    preferences, and security settings.
    
    Meta:
        model: UserProfile
        fields: All user-editable profile fields
    """
    
    # Add User model fields
    first_name = forms.CharField(
        max_length=30,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': _('First Name'),
        }),
        label=_('First Name')
    )
    
    last_name = forms.CharField(
        max_length=30,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': _('Last Name'),
        }),
        label=_('Last Name')
    )
    
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': _('Email Address'),
        }),
        label=_('Email Address')
    )
    
    class Meta:
        model = UserProfile
        fields = [
            'phone', 'avatar', 'timezone', 'language',
            'email_notifications', 'sms_notifications',
            'two_factor_enabled', 'session_timeout'
        ]
        
        widgets = {
            'phone': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Phone Number'),
                'pattern': r'^\+?[1-9]\d{1,14}$',
            }),
            'avatar': forms.FileInput(attrs={
                'class': 'form-control',
                'accept': 'image/*',
            }),
            'timezone': forms.Select(attrs={
                'class': 'form-select',
            }),
            'language': forms.Select(attrs={
                'class': 'form-select',
            }),
            'email_notifications': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
            'sms_notifications': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
            'two_factor_enabled': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
            'session_timeout': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '5',
                'max': '1440',
                'step': '5',
            }),
        }
        
        help_texts = {
            'phone': _('Enter your phone number with country code (e.g., +1234567890)'),
            'avatar': _('Upload a profile picture (max 2MB, JPG/PNG only)'),
            'timezone': _('Select your local timezone'),
            'language': _('Choose your preferred language'),
            'email_notifications': _('Receive notifications via email'),
            'sms_notifications': _('Receive notifications via SMS'),
            'two_factor_enabled': _('Enable two-factor authentication for enhanced security'),
            'session_timeout': _('Session timeout in minutes (5-1440)'),
        }
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with user data.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Populate User model fields if instance exists
        if self.instance and self.instance.user:
            self.fields['first_name'].initial = self.instance.user.first_name
            self.fields['last_name'].initial = self.instance.user.last_name
            self.fields['email'].initial = self.instance.user.email
    
    def clean_phone(self) -> Optional[str]:
        """
        Validate phone number format.
        
        Returns:
            Optional[str]: Validated phone number
        
        Raises:
            ValidationError: If phone number is invalid
        """
        phone = self.cleaned_data.get('phone')
        
        if phone:
            validate_phone_number(phone)
        
        return phone
    
    def clean_timezone(self) -> str:
        """
        Validate timezone.
        
        Returns:
            str: Validated timezone
        
        Raises:
            ValidationError: If timezone is invalid
        """
        timezone_name = self.cleaned_data.get('timezone')
        
        if timezone_name:
            validate_timezone(timezone_name)
        
        return timezone_name
    
    def clean_language(self) -> str:
        """
        Validate language code.
        
        Returns:
            str: Validated language code
        
        Raises:
            ValidationError: If language code is invalid
        """
        language = self.cleaned_data.get('language')
        
        if language:
            validate_language_code(language)
        
        return language
    
    def clean_avatar(self) -> Optional[Any]:
        """
        Validate avatar image file.
        
        Returns:
            Optional[Any]: Validated avatar file
        
        Raises:
            ValidationError: If avatar file is invalid
        """
        avatar = self.cleaned_data.get('avatar')
        
        if avatar:
            # Check file size (max 2MB)
            if avatar.size > 2 * 1024 * 1024:
                raise ValidationError(_('Avatar file size must be less than 2MB.'))
            
            # Check file type
            allowed_types = ['image/jpeg', 'image/png', 'image/gif']
            if avatar.content_type not in allowed_types:
                raise ValidationError(_('Avatar must be a JPEG, PNG, or GIF image.'))
        
        return avatar
    
    def save(self, commit: bool = True) -> UserProfile:
        """
        Save the form data to both User and UserProfile models.
        
        Args:
            commit (bool): Whether to save to database
        
        Returns:
            UserProfile: The saved user profile instance
        """
        profile = super().save(commit=False)
        
        # Update User model fields
        if profile.user:
            profile.user.first_name = self.cleaned_data.get('first_name', '')
            profile.user.last_name = self.cleaned_data.get('last_name', '')
            profile.user.email = self.cleaned_data.get('email', '')
            
            if commit:
                profile.user.save()
        
        if commit:
            profile.save()
        
        return profile


class UserCreationForm(UserCreationForm):
    """
    Enhanced user creation form with additional fields.
    
    This form extends Django's built-in user creation form
    with additional fields and validation.
    
    Meta:
        model: User
        fields: Extended user creation fields
    """
    
    email = forms.EmailField(
        required=True,
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': _('Email Address'),
        }),
        label=_('Email Address'),
        help_text=_('A valid email address is required')
    )
    
    first_name = forms.CharField(
        max_length=30,
        required=True,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': _('First Name'),
        }),
        label=_('First Name')
    )
    
    last_name = forms.CharField(
        max_length=30,
        required=True,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': _('Last Name'),
        }),
        label=_('Last Name')
    )
    
    user_type = forms.ChoiceField(
        choices=UserProfile.USER_TYPES,
        widget=forms.Select(attrs={
            'class': 'form-select',
        }),
        label=_('User Type'),
        help_text=_('Select the user\'s role in the system')
    )
    
    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email', 'password1', 'password2']
        
        widgets = {
            'username': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Username'),
            }),
        }
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with custom widget attributes.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Customize password field widgets
        self.fields['password1'].widget.attrs.update({
            'class': 'form-control',
            'placeholder': _('Password'),
        })
        
        self.fields['password2'].widget.attrs.update({
            'class': 'form-control',
            'placeholder': _('Confirm Password'),
        })
        
        # Update help texts
        self.fields['password1'].help_text = _(
            'Password must be at least 8 characters long and contain '
            'uppercase, lowercase, numbers, and special characters.'
        )
    
    def clean_email(self) -> str:
        """
        Validate email uniqueness.
        
        Returns:
            str: Validated email address
        
        Raises:
            ValidationError: If email already exists
        """
        email = self.cleaned_data.get('email', '').lower()
        
        if User.objects.filter(email=email).exists():
            raise ValidationError(_('A user with this email address already exists.'))
        
        return email
    
    def clean_password1(self) -> str:
        """
        Validate password strength.
        
        Returns:
            str: Validated password
        
        Raises:
            ValidationError: If password doesn't meet strength requirements
        """
        password = self.cleaned_data.get('password1')
        
        if password:
            validate_password_strength(password)
        
        return password
    
    def save(self, commit: bool = True) -> User:
        """
        Save the user and create associated profile.
        
        Args:
            commit (bool): Whether to save to database
        
        Returns:
            User: The created user instance
        """
        user = super().save(commit=False)
        user.email = self.cleaned_data['email']
        
        if commit:
            user.save()
            
            # Create user profile
            UserProfile.objects.create(
                user=user,
                user_type=self.cleaned_data['user_type']
            )
        
        return user


# ============================================================================
# Role and Permission Management Forms
# ============================================================================

class RoleForm(forms.ModelForm):
    """
    Role creation and editing form.
    
    This form handles role management including permissions assignment.
    
    Meta:
        model: Role
        fields: All role fields except system fields
    """
    
    class Meta:
        model = Role
        fields = [
            'name', 'display_name', 'description', 'permissions',
            'parent_role', 'is_active', 'color', 'icon'
        ]
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Role Name'),
                'pattern': r'^[a-zA-Z0-9_]+$',
            }),
            'display_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Display Name'),
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': _('Role Description'),
            }),
            'permissions': forms.CheckboxSelectMultiple(attrs={
                'class': 'form-check-input',
            }),
            'parent_role': forms.Select(attrs={
                'class': 'form-select',
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
            'color': forms.TextInput(attrs={
                'class': 'form-control',
                'type': 'color',
            }),
            'icon': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Icon Class'),
            }),
        }
        
        help_texts = {
            'name': _('Unique identifier for the role (letters, numbers, underscores only)'),
            'display_name': _('Human-readable name for the role'),
            'description': _('Detailed description of the role\'s purpose'),
            'permissions': _('Select permissions to grant to this role'),
            'parent_role': _('Parent role for inheritance (optional)'),
            'is_active': _('Whether this role is currently active'),
            'color': _('Color for UI display'),
            'icon': _('Icon class for UI display (e.g., fas fa-user)'),
        }
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with custom querysets.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Filter permissions by active status
        self.fields['permissions'].queryset = Permission.objects.filter(
            is_active=True
        ).order_by('resource', 'action')
        
        # Filter parent roles (exclude self if editing)
        parent_queryset = Role.objects.filter(is_active=True)
        if self.instance and self.instance.pk:
            parent_queryset = parent_queryset.exclude(pk=self.instance.pk)
        self.fields['parent_role'].queryset = parent_queryset
        
        # Add empty option for parent role
        self.fields['parent_role'].empty_label = _('No Parent Role')
    
    def clean_name(self) -> str:
        """
        Validate role name format and uniqueness.
        
        Returns:
            str: Validated role name
        
        Raises:
            ValidationError: If role name is invalid
        """
        name = self.cleaned_data.get('name', '').strip().lower()
        
        if not name:
            raise ValidationError(_('Role name is required.'))
        
        # Check format
        if not re.match(r'^[a-zA-Z0-9_]+$', name):
            raise ValidationError(_('Role name can only contain letters, numbers, and underscores.'))
        
        # Check uniqueness
        queryset = Role.objects.filter(name=name)
        if self.instance and self.instance.pk:
            queryset = queryset.exclude(pk=self.instance.pk)
        
        if queryset.exists():
            raise ValidationError(_('A role with this name already exists.'))
        
        return name
    
    def clean_parent_role(self) -> Optional[Role]:
        """
        Validate parent role to prevent circular inheritance.
        
        Returns:
            Optional[Role]: Validated parent role
        
        Raises:
            ValidationError: If parent role creates circular inheritance
        """
        parent_role = self.cleaned_data.get('parent_role')
        
        if parent_role and self.instance and self.instance.pk:
            # Check for circular inheritance
            current_parent = parent_role
            while current_parent:
                if current_parent.pk == self.instance.pk:
                    raise ValidationError(_('Circular inheritance detected. A role cannot inherit from itself.'))
                current_parent = current_parent.parent_role
        
        return parent_role


class PermissionForm(forms.ModelForm):
    """
    Permission creation and editing form.
    
    This form handles permission management.
    
    Meta:
        model: Permission
        fields: All permission fields except system fields
    """
    
    class Meta:
        model = Permission
        fields = [
            'name', 'display_name', 'description', 'resource',
            'action', 'is_active'
        ]
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Permission Name'),
                'pattern': r'^[a-zA-Z0-9_\.]+$',
            }),
            'display_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Display Name'),
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': _('Permission Description'),
            }),
            'resource': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Resource Name'),
            }),
            'action': forms.Select(attrs={
                'class': 'form-select',
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
        }
        
        help_texts = {
            'name': _('Unique identifier for the permission (e.g., accounts.view_user)'),
            'display_name': _('Human-readable name for the permission'),
            'description': _('Detailed description of what this permission allows'),
            'resource': _('Resource this permission applies to (e.g., user, campaign)'),
            'action': _('Action this permission allows'),
            'is_active': _('Whether this permission is currently active'),
        }
    
    def clean_name(self) -> str:
        """
        Validate permission name format and uniqueness.
        
        Returns:
            str: Validated permission name
        
        Raises:
            ValidationError: If permission name is invalid
        """
        name = self.cleaned_data.get('name', '').strip().lower()
        
        if not name:
            raise ValidationError(_('Permission name is required.'))
        
        # Check format (allow dots for namespacing)
        if not re.match(r'^[a-zA-Z0-9_\.]+$', name):
            raise ValidationError(_('Permission name can only contain letters, numbers, underscores, and dots.'))
        
        # Check uniqueness
        queryset = Permission.objects.filter(name=name)
        if self.instance and self.instance.pk:
            queryset = queryset.exclude(pk=self.instance.pk)
        
        if queryset.exists():
            raise ValidationError(_('A permission with this name already exists.'))
        
        return name


class UserRoleForm(forms.ModelForm):
    """
    User role assignment form.
    
    This form handles assigning roles to users.
    
    Meta:
        model: UserRole
        fields: User role assignment fields
    """
    
    class Meta:
        model = UserRole
        fields = ['user', 'role', 'granted_by', 'expires_at', 'is_active']
        
        widgets = {
            'user': forms.Select(attrs={
                'class': 'form-select',
            }),
            'role': forms.Select(attrs={
                'class': 'form-select',
            }),
            'granted_by': forms.Select(attrs={
                'class': 'form-select',
            }),
            'expires_at': forms.DateTimeInput(attrs={
                'class': 'form-control',
                'type': 'datetime-local',
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
        }
        
        help_texts = {
            'user': _('Select the user to assign the role to'),
            'role': _('Select the role to assign'),
            'granted_by': _('User who is granting this role'),
            'expires_at': _('When this role assignment expires (optional)'),
            'is_active': _('Whether this role assignment is currently active'),
        }
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with filtered querysets.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Filter active users and roles
        self.fields['user'].queryset = User.objects.filter(is_active=True)
        self.fields['role'].queryset = Role.objects.filter(is_active=True)
        self.fields['granted_by'].queryset = User.objects.filter(is_active=True)
    
    def clean(self) -> Dict[str, Any]:
        """
        Validate the form data.
        
        Returns:
            Dict[str, Any]: Cleaned form data
        
        Raises:
            ValidationError: If validation fails
        """
        cleaned_data = super().clean()
        user = cleaned_data.get('user')
        role = cleaned_data.get('role')
        expires_at = cleaned_data.get('expires_at')
        
        # Check for duplicate role assignment
        if user and role:
            queryset = UserRole.objects.filter(user=user, role=role, is_active=True)
            if self.instance and self.instance.pk:
                queryset = queryset.exclude(pk=self.instance.pk)
            
            if queryset.exists():
                raise ValidationError(_('This user already has this role assigned.'))
        
        # Validate expiration date
        if expires_at and expires_at <= timezone.now():
            raise ValidationError(_('Expiration date must be in the future.'))
        
        return cleaned_data


# ============================================================================
# API and Security Forms
# ============================================================================

class APIKeyForm(forms.ModelForm):
    """
    API key creation and management form.
    
    This form handles API key creation and configuration.
    
    Meta:
        model: APIKey
        fields: API key configuration fields
    """
    
    class Meta:
        model = APIKey
        fields = [
            'name', 'description', 'permissions', 'expires_at',
            'rate_limit', 'allowed_ips', 'is_active'
        ]
        
        widgets = {
            'name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('API Key Name'),
            }),
            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': _('API Key Description'),
            }),
            'permissions': forms.CheckboxSelectMultiple(attrs={
                'class': 'form-check-input',
            }),
            'expires_at': forms.DateTimeInput(attrs={
                'class': 'form-control',
                'type': 'datetime-local',
            }),
            'rate_limit': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '1',
                'max': '10000',
            }),
            'allowed_ips': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': _('192.168.1.1, 10.0.0.1'),
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
        }
        
        help_texts = {
            'name': _('Descriptive name for the API key'),
            'description': _('Purpose and usage of this API key'),
            'permissions': _('Select permissions for this API key'),
            'expires_at': _('When this API key expires (optional)'),
            'rate_limit': _('Maximum requests per hour (1-10000)'),
            'allowed_ips': _('Comma-separated list of allowed IP addresses (optional)'),
            'is_active': _('Whether this API key is currently active'),
        }
    
    def __init__(self, *args, **kwargs):
        """
        Initialize the form with filtered permissions.
        
        Args:
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
        """
        super().__init__(*args, **kwargs)
        
        # Filter active permissions
        self.fields['permissions'].queryset = Permission.objects.filter(
            is_active=True
        ).order_by('resource', 'action')
    
    def clean_allowed_ips(self) -> str:
        """
        Validate IP address list.
        
        Returns:
            str: Validated IP address list
        
        Raises:
            ValidationError: If IP addresses are invalid
        """
        allowed_ips = self.cleaned_data.get('allowed_ips', '').strip()
        
        if allowed_ips:
            # Split by comma and validate each IP
            ip_list = [ip.strip() for ip in allowed_ips.split(',')]
            
            for ip in ip_list:
                if ip:  # Skip empty strings
                    try:
                        # Basic IP validation
                        import ipaddress
                        ipaddress.ip_address(ip)
                    except ValueError:
                        raise ValidationError(_(f'Invalid IP address: {ip}'))
        
        return allowed_ips
    
    def clean_expires_at(self) -> Optional[Any]:
        """
        Validate expiration date.
        
        Returns:
            Optional[Any]: Validated expiration date
        
        Raises:
            ValidationError: If expiration date is invalid
        """
        expires_at = self.cleaned_data.get('expires_at')
        
        if expires_at and expires_at <= timezone.now():
            raise ValidationError(_('Expiration date must be in the future.'))
        
        return expires_at


class UserAccessForm(forms.ModelForm):
    """
    User access credentials form.
    
    This form handles external service access credentials.
    
    Meta:
        model: UserAccess
        fields: User access configuration fields
    """
    
    # Add password confirmation field
    password_confirm = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': _('Confirm Password'),
        }),
        label=_('Confirm Password'),
        help_text=_('Re-enter the password for confirmation')
    )
    
    class Meta:
        model = UserAccess
        fields = [
            'service_name', 'service_type', 'username', 'password',
            'host', 'port', 'additional_config', 'is_active'
        ]
        
        widgets = {
            'service_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Service Name'),
            }),
            'service_type': forms.Select(attrs={
                'class': 'form-select',
            }),
            'username': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Username'),
            }),
            'password': forms.PasswordInput(attrs={
                'class': 'form-control',
                'placeholder': _('Password'),
            }),
            'host': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': _('Host/Server Address'),
            }),
            'port': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '1',
                'max': '65535',
            }),
            'additional_config': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': _('Additional configuration in JSON format'),
            }),
            'is_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
        }
        
        help_texts = {
            'service_name': _('Descriptive name for the service'),
            'service_type': _('Type of external service'),
            'username': _('Username for the external service'),
            'password': _('Password for the external service'),
            'host': _('Host or server address'),
            'port': _('Port number (1-65535)'),
            'additional_config': _('Additional configuration in JSON format'),
            'is_active': _('Whether this access is currently active'),
        }
    
    def clean_additional_config(self) -> Dict[str, Any]:
        """
        Validate JSON configuration.
        
        Returns:
            Dict[str, Any]: Validated JSON configuration
        
        Raises:
            ValidationError: If JSON is invalid
        """
        config = self.cleaned_data.get('additional_config', '{}')
        
        if config:
            try:
                json.loads(config)
            except json.JSONDecodeError:
                raise ValidationError(_('Additional configuration must be valid JSON.'))
        
        return config
    
    def clean(self) -> Dict[str, Any]:
        """
        Validate password confirmation.
        
        Returns:
            Dict[str, Any]: Cleaned form data
        
        Raises:
            ValidationError: If passwords don't match
        """
        cleaned_data = super().clean()
        password = cleaned_data.get('password')
        password_confirm = cleaned_data.get('password_confirm')
        
        if password and password_confirm and password != password_confirm:
            raise ValidationError(_('The two password fields didn\'t match.'))
        
        return cleaned_data