from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _
from .models import UserRole, Department

User = get_user_model()

class MinisterUserForm(forms.ModelForm):
    """Form for creating Heads of Sections by Director General."""
    password = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        required=True,
        help_text=_("Enter a strong password for the new user.")
    )
    
    role_type = forms.CharField(
        widget=forms.HiddenInput(),
        initial='head'
    )
    
    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name', 'department', 'password']
        widgets = {
            'email': forms.EmailInput(attrs={'class': 'form-control', 'required': True}),
            'first_name': forms.TextInput(attrs={'class': 'form-control', 'required': True}),
            'last_name': forms.TextInput(attrs={'class': 'form-control', 'required': True}),
            'department': forms.Select(attrs={'class': 'form-control', 'required': True}),
        }
        labels = {
            'email': _('Email Address'),
            'first_name': _('First Name'),
            'last_name': _('Last Name'),
            'department': _('Section')
        }
    
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        role_type = kwargs.pop('role_type', 'head')  # Default to 'head' for this form
        super().__init__(*args, **kwargs)
        
        # Set role type
        self.fields['role_type'].initial = role_type
        
        # Filter departments to only show sections under the director's department
        if self.request and hasattr(self.request.user, 'department') and self.request.user.department:
            self.fields['department'].queryset = Department.objects.filter(
                parent=self.request.user.department
            )
        else:
            # If no department is set for the director, show no departments
            self.fields['department'].queryset = Department.objects.none()
            
        # Make department required
        self.fields['department'].required = True
    
    def save(self, commit=True):
        user = super().save(commit=False)
        user.username = self.cleaned_data['email']  # Use email as username
        user.is_active = True
        user.is_staff = True
        
        # Set password if one was provided
        if 'password' in self.cleaned_data:
            user.set_password(self.cleaned_data['password'])
            
        if commit:
            user.save()
            
            # Add to Head of Section group if it exists
            from django.contrib.auth.models import Group
            try:
                head_group = Group.objects.get(name='Head of Section')
                user.groups.add(head_group)
            except Group.DoesNotExist:
                pass
        
        # Set the role based on role_type
        role_type = self.cleaned_data['role_type']
        if role_type == 'director':
            user.role = UserRole.objects.get(name='director')
        elif role_type == 'head':
            user.role = UserRole.objects.get(name='head')
        
        if commit:
            user.save()
        return user

class UserForm(forms.ModelForm):
    """Form for creating and updating users."""
    password = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput(attrs={'class': 'form-control'}),
        required=False,
        help_text=_("Leave blank if not changing the password.")
    )
    
    class Meta:
        model = User
        fields = [
            'email', 'first_name', 'last_name', 'role', 'department',
            'is_active', 'is_staff', 'is_superuser'
        ]
        widgets = {
            'email': forms.EmailInput(attrs={'class': 'form-control'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control'}),
            'role': forms.Select(attrs={'class': 'form-control'}),
            'department': forms.Select(attrs={'class': 'form-control'}),
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance.pk:
            self.fields['password'].help_text = _(
                "Raw passwords are not stored, so there is no way to see this "
                "user's password, but you can change the password using "
                "<a href=\"../password/\">this form</a>."
            )
    
    def save(self, commit=True):
        user = super().save(commit=False)
        password = self.cleaned_data.get("password")
        if password:
            user.set_password(password)
        if commit:
            user.save()
            self.save_m2m()
        return user

class UserRoleForm(forms.ModelForm):
    """Form for creating and updating user roles."""
    class Meta:
        model = UserRole
        fields = ['name', 'permissions']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'permissions': forms.SelectMultiple(
                attrs={
                    'class': 'form-control select2',
                    'data-placeholder': 'Select permissions'
                }
            ),
        }

class DepartmentForm(forms.ModelForm):
    """Form for creating and updating departments."""
    class Meta:
        model = Department
        fields = ['name', 'description', 'parent']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
            'parent': forms.Select(attrs={'class': 'form-control'}),
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Prevent a department from being its own parent
        if self.instance.pk:
            self.fields['parent'].queryset = Department.objects.exclude(pk=self.instance.pk)
        else:
            self.fields['parent'].queryset = Department.objects.all()
