from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from .models import Profile
import re


class SignUpForm(UserCreationForm):
    name = forms.CharField(max_length=100, required=True, label="Full Name")
    email = forms.EmailField(required=True, label="Email Address")
    accept_terms = forms.BooleanField(required=True, label="I accept the Terms of Service")

    class Meta:
        model = User
        fields = ['name', 'email', 'password1', 'password2', 'accept_terms']

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise ValidationError("This email is already registered.")
        return email

    def clean_password1(self):
        password1 = self.cleaned_data.get('password1')
        if password1:
            # Basic password length check
            if len(password1) < 6:
                raise ValidationError("Password must be at least 6 characters long.")
            
            # Check for very common passwords only
            very_common_passwords = ['password', '123456', '123456789', 'qwerty', 'abc123', 'admin']
            if password1.lower() in very_common_passwords:
                raise ValidationError("This password is too common. Please choose a more secure password.")
        
        return password1

    def clean(self):
        cleaned_data = super().clean()
        password1 = cleaned_data.get('password1')
        password2 = cleaned_data.get('password2')
        
        if password1 and password2 and password1 != password2:
            raise ValidationError("The passwords do not match.")
        
        return cleaned_data

    def save(self, commit=True):
        user = super().save(commit=False)
        user.username = self.cleaned_data['email']
        user.first_name = self.cleaned_data['name']
        user.email = self.cleaned_data['email']
        
        if commit:
            user.save()
            # Create or update profile
            profile = Profile.objects.get_or_create(user=user)[0]
            profile.save()
            
        return user


class LoginForm(forms.Form):
    email = forms.EmailField(label="Email", required=True)
    password = forms.CharField(widget=forms.PasswordInput, required=True)
    remember_me = forms.BooleanField(required=False, initial=False)


class ForgotPasswordForm(forms.Form):
    email = forms.EmailField(label="Email", required=True)

    def clean_email(self):
        email = self.cleaned_data['email']
        if not User.objects.filter(email=email).exists():
            raise ValidationError("No account found with this email address.")
        return email


class ResetPasswordForm(forms.Form):
    password1 = forms.CharField(
        label="New Password",
        widget=forms.PasswordInput
    )
    password2 = forms.CharField(
        label="Confirm Password",
        widget=forms.PasswordInput
    )

    def clean_password1(self):
        password1 = self.cleaned_data.get('password1')
        if password1:
            # Basic password length check
            if len(password1) < 6:
                raise ValidationError("Password must be at least 6 characters long.")
            
            # Check for very common passwords only
            very_common_passwords = ['password', '123456', '123456789', 'qwerty', 'abc123', 'admin']
            if password1.lower() in very_common_passwords:
                raise ValidationError("This password is too common. Please choose a more secure password.")
        
        return password1

    def clean(self):
        cleaned_data = super().clean()
        password1 = cleaned_data.get("password1")
        password2 = cleaned_data.get("password2")
        
        if password1 and password2 and password1 != password2:
            raise ValidationError("The passwords do not match.")
        
        return cleaned_data


class ProfileUpdateForm(forms.ModelForm):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    
    class Meta:
        model = Profile
        fields = ['bio', 'profile_image', 'email_notifications', 'push_notifications']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance and self.instance.user:
            self.fields['name'].initial = self.instance.user.first_name
            self.fields['email'].initial = self.instance.user.email

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.exclude(id=self.instance.user.id).filter(email=email).exists():
            raise ValidationError("This email is already in use by another account.")
        return email


class NameUpdateForm(forms.Form):
    first_name = forms.CharField(
        max_length=100,
        label="First Name",
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter first name'})
    )
    last_name = forms.CharField(
        max_length=100,
        label="Last Name", 
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter last name'})
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)
        if user:
            self.fields['first_name'].initial = user.first_name
            self.fields['last_name'].initial = user.last_name


class PasswordChangeForm(forms.Form):
    current_password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter current password'}),
        required=True,
        label="Current Password"
    )
    new_password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter new password'}),
        label="New Password"
    )
    confirm_password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm new password'}),
        label="Confirm New Password"
    )

    def __init__(self, user, *args, **kwargs):
        self.user = user
        super().__init__(*args, **kwargs)

    def clean_current_password(self):
        current_password = self.cleaned_data['current_password']
        if not self.user.check_password(current_password):
            raise ValidationError("Current password is incorrect.")
        return current_password

    def clean_new_password(self):
        new_password = self.cleaned_data.get('new_password')
        if new_password:
            # Basic password length check
            if len(new_password) < 6:
                raise ValidationError("Password must be at least 6 characters long.")
            
            # Check for very common passwords only
            very_common_passwords = ['password', '123456', '123456789', 'qwerty', 'abc123', 'admin']
            if new_password.lower() in very_common_passwords:
                raise ValidationError("This password is too common. Please choose a more secure password.")
        
        return new_password

    def clean(self):
        cleaned_data = super().clean()
        new_password = cleaned_data.get("new_password")
        confirm_password = cleaned_data.get("confirm_password")
        
        if new_password and confirm_password and new_password != confirm_password:
            raise ValidationError("The new passwords do not match.")
        
        return cleaned_data


class SecuritySettingsForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['two_factor_enabled']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
