from django import forms
from django.contrib.auth.models import User, Group, Permission
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth import authenticate
from tenants.models import Tenant, TenantUser

# Form for tenant login with tenant code
class TenantLoginForm(forms.Form):
    tenant_code = forms.CharField(
        max_length=20,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter organization code',
            'required': True
        }),
        label='Organization Code'
    )
    username = forms.CharField(
        max_length=150,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter username',
            'required': True
        })
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter password',
            'required': True
        })
    )

    def clean(self):
        cleaned_data = super().clean()
        tenant_code = cleaned_data.get('tenant_code')
        username = cleaned_data.get('username')
        password = cleaned_data.get('password')

        if tenant_code and username and password:
            # Verify tenant exists and is active
            try:
                tenant = Tenant.objects.get(tenant_code=tenant_code, status__in=['active', 'trial'])
            except Tenant.DoesNotExist:
                raise forms.ValidationError('Invalid organization code.')

            # Authenticate user
            user = authenticate(username=username, password=password)
            if not user:
                raise forms.ValidationError('Invalid username or password.')
            
            # Additional security: Check if user account is active
            if not user.is_active:
                raise forms.ValidationError('Your account has been deactivated. Please contact support.')

            # Verify user belongs to this tenant and has active access
            try:
                tenant_user = TenantUser.objects.get(user=user, tenant=tenant, is_active=True)
                
                # Security check: Only enforce tenant prefix for usernames with actual tenant code prefix
                if '_' in user.username:
                    prefix = user.username.split('_', 1)[0]
                    # Check if prefix is an actual tenant code in database
                    if Tenant.objects.filter(tenant_code__iexact=prefix).exists():
                        # Username has a real tenant prefix, verify it matches this tenant
                        if prefix.lower() != tenant_code.lower():
                            raise forms.ValidationError('Access denied to this organization.')
                # For legacy usernames (no tenant format), rely on TenantUser membership check
                
                cleaned_data['user'] = user
                cleaned_data['tenant'] = tenant
                cleaned_data['tenant_user'] = tenant_user
                
            except TenantUser.DoesNotExist:
                raise forms.ValidationError('You do not have access to this organization.')

        return cleaned_data

# Form for creating and editing users with group assignment
class UserForm(UserCreationForm):
    email = forms.EmailField(required=True)
    groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2', 'groups']

# Form for editing existing users
class EditUserForm(UserChangeForm):
    password = None  # Hide the password field in the edit form
    email = forms.EmailField(required=True)
    groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(), required=False, widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = User
        fields = ['username', 'email', 'groups']

# Form for creating and editing groups
class GroupForm(forms.ModelForm):
    class Meta:
        model = Group
        fields = ['name']

# Custom user creation form
class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2', 'groups']

# Custom user change form
class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name', 'groups']

# Form for assigning permissions to groups
class GroupPermissionForm(forms.ModelForm):
    permissions = forms.ModelMultipleChoiceField(
        queryset=Permission.objects.all(),
        widget=forms.CheckboxSelectMultiple,
        required=False
    )

    class Meta:
        model = Group
        fields = ['permissions']

# Form for editing user profile with password change
class EditProfileForm(forms.ModelForm):
    profile_picture = forms.ImageField(
        label='Profile Picture',
        widget=forms.FileInput(attrs={'class': 'form-control', 'accept': 'image/*'}),
        required=False,
        help_text='Upload a profile picture (JPG, PNG, GIF - Max 2MB)'
    )
    new_password1 = forms.CharField(
        label='New Password',
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter new password'}),
        required=False,
        help_text='Leave blank if you don\'t want to change your password'
    )
    new_password2 = forms.CharField(
        label='Confirm New Password',
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm new password'}),
        required=False
    )

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']
        widgets = {
            'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter first name'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter last name'}),
            'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter email address'}),
        }

    def clean_new_password2(self):
        password1 = self.cleaned_data.get('new_password1')
        password2 = self.cleaned_data.get('new_password2')
        
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError("Passwords don't match")
        elif password1 and not password2:
            raise forms.ValidationError("Please confirm your new password")
        elif password2 and not password1:
            raise forms.ValidationError("Please enter your new password")
        
        return password2

    def save(self, commit=True):
        user = super().save(commit=False)
        
        new_password = self.cleaned_data.get('new_password1')
        if new_password:
            user.set_password(new_password)
        
        if commit:
            user.save()
        
        return user