from django import forms
from django.contrib.auth.models import User
from .models import UserProfile, MyModel, Term, Subscriber, ContactMessage
from django.core.exceptions import ValidationError
import re
import logging
from django.contrib.auth.forms import AuthenticationForm



from django.contrib.auth.password_validation import validate_password
from django.utils.translation import gettext_lazy as _  # Tambahkan impor ini

from django.contrib.auth import authenticate

from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV3  # Tambahkan ini!
from django import forms
from .models import Report

class ReportForm(forms.ModelForm):
    class Meta:
        model = Report
        fields = ['url', 'description']
        widgets = {
            'url': forms.URLInput(attrs={'class': 'form-control', 'placeholder': 'Masukkan URL halaman'}),
            'description': forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Jelaskan masalahnya', 'rows': 4}),
        }


class RecaptchaForm(forms.Form):
    recaptcha = ReCaptchaField(widget=ReCaptchaV3, label="")

class CustomAuthenticationForm(AuthenticationForm):
    recaptcha = ReCaptchaField()
    
    error_messages = {
        'invalid_login': 'Nama pengguna atau kata sandi salah. Pastikan informasi yang Anda masukkan benar.',
        'inactive': 'Akun Anda belum diaktifkan. Silakan periksa email Anda untuk aktivasi.'
    }

    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise ValidationError(self.error_messages['inactive'], code='inactive')

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

        if username and password:
            user = authenticate(username=username, password=password)
            if user is None:
                raise ValidationError(self.error_messages['invalid_login'], code='invalid_login')

        return cleaned_data





class ContactForm(forms.ModelForm):
    class Meta:
        model = ContactMessage
        fields = ['name', 'email', 'message']
        widgets = {
            'name': forms.TextInput(attrs={'class': 'w-full p-3 border rounded-lg', 'placeholder': 'Masukan nama Anda'}),
            'email': forms.EmailInput(attrs={'class': 'w-full p-3 border rounded-lg', 'placeholder': 'Masukan email Anda'}),
            'message': forms.Textarea(attrs={'class': 'w-full p-3 border rounded-lg', 'placeholder': 'Tulis pesan Anda minimal 10 karakter..'}),
        }



class SubscribeForm(forms.ModelForm):
    class Meta:
        model = Subscriber
        fields = ['email']
        widgets = {
            'email': forms.EmailInput(attrs={
                'class': 'py-3 px-4 block w-full border-transparent rounded-lg text-sm dark:bg-neutral-900 dark:border-transparent dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600',
                'placeholder': 'Enter your email',
                'required': 'required'
            }),
        }

class TermForm(forms.ModelForm):
    class Meta:
        model = Term
        fields = ['name', 'definition', 'my_models']  # Updated to ManyToManyField
        widgets = {
            'my_models': forms.CheckboxSelectMultiple(),  # Use appropriate widget for ManyToManyField
        }

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['data', 'category', 'year']  # Add the term field


class UserSignupForm(forms.ModelForm):
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': _('Enter your password')}),
        label=_("Password")
    )
    confirm_password = forms.CharField(
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': _('Confirm your password')}),
        label=_("Confirm Password")
    )
    agree = forms.BooleanField(
        required=True,
        label=_("I agree to the terms and conditions")
    )
    subscribe = forms.BooleanField(
        required=False,
        label=_("Subscribe to our newsletter")
    )

    class Meta:
        model = User
        fields = ['username', 'email', 'password', 'confirm_password']
        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('Enter your username')}),
            'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': _('Enter your email address')}),
        }

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

        if password and confirm_password and password != confirm_password:
            self.add_error('confirm_password', _("The passwords you entered do not match. Please try again."))

        return cleaned_data



from django import forms
from django.contrib.auth.models import User
from .models import UserProfile
from cryptography.fernet import Fernet, InvalidToken
from django.conf import settings

# Inisialisasi cipher_suite dengan kunci dari settings
cipher_suite = Fernet(settings.ENCRYPTION_KEY)

class UserProfileForm(forms.ModelForm):
    email = forms.EmailField(required=True, label="Email")
    username = forms.CharField(required=True, label="Username")

    class Meta:
        model = UserProfile
        fields = ['first_name', 'last_name', 'job', 'province', 'birth_date', 'profile_picture']

    def __init__(self, *args, **kwargs):
        self.user_instance = kwargs.pop('user_instance', None)
        super(UserProfileForm, self).__init__(*args, **kwargs)

        # Jika ada instance User, isi initial value untuk email dan username
        if self.user_instance:
            self.fields['email'].initial = self.user_instance.email
            self.fields['username'].initial = self.user_instance.username

        # Dekripsi data sebelum ditampilkan
        if self.instance:
            self.fields['first_name'].initial = self.decrypt_data(self.instance.first_name)
            self.fields['last_name'].initial = self.decrypt_data(self.instance.last_name)
            self.fields['job'].initial = self.decrypt_data(self.instance.job)
            self.fields['province'].initial = self.decrypt_data(self.instance.province)

    def decrypt_data(self, encrypted_data):
        """Mendekripsi data sebelum ditampilkan di form."""
        if not encrypted_data:
            return ""
        try:
            return cipher_suite.decrypt(encrypted_data.encode()).decode()
        except (InvalidToken, AttributeError, TypeError):
            return "Invalid Data"

    def clean_first_name(self):
        first_name = self.cleaned_data.get('first_name')  # Tidak ada default string kosong
        if first_name:  # Hanya strip jika first_name tidak None
            return first_name.strip().capitalize()
        return None  # Kembalikan None jika tidak ada input


    def clean_last_name(self):
        last_name = self.cleaned_data.get('last_name')  # Bisa None
        if last_name:  # Pastikan tidak memanggil .strip() pada None
            return last_name.strip().capitalize()
        return None  # Kembalikan None jika tidak ada input


    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exclude(pk=getattr(self.user_instance, 'pk', None)).exists():
            raise forms.ValidationError("Username already exists. Please choose a different one.")
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exclude(pk=getattr(self.user_instance, 'pk', None)).exists():
            raise forms.ValidationError("Email already exists. Please choose a different one.")
        return email

def save(self, commit=True):
    profile = super(UserProfileForm, self).save(commit=False)

    # Enkripsi hanya jika field tidak kosong
    if self.cleaned_data.get('first_name'):
        profile.first_name = cipher_suite.encrypt(self.cleaned_data['first_name'].encode()).decode()
    else:
        profile.first_name = None  # Simpan None jika kosong

    if self.cleaned_data.get('last_name'):
        profile.last_name = cipher_suite.encrypt(self.cleaned_data['last_name'].encode()).decode()
    else:
        profile.last_name = None

    if self.cleaned_data.get('job'):
        profile.job = cipher_suite.encrypt(self.cleaned_data['job'].encode()).decode()
    else:
        profile.job = None

    if self.cleaned_data.get('province'):
        profile.province = cipher_suite.encrypt(self.cleaned_data['province'].encode()).decode()
    else:
        profile.province = None

    # Simpan username dan email ke User
    if self.user_instance:
        self.user_instance.email = self.cleaned_data['email']
        self.user_instance.username = self.cleaned_data['username']
        if commit:
            self.user_instance.save()

    # Menyimpan gambar sebagai BLOB
    profile_picture_file = self.cleaned_data.get('profile_picture')
    if profile_picture_file:
        profile.profile_picture = profile_picture_file.read()

    if commit:
        profile.save()

    return profile


   