from django import forms
from users.models import Company, User, Client, Countries, ClientFrequentFlyer, Airlines, ClientPassport, AssocClientCompany, ClientDocument, ClientVisa, ClientTravelInsurance
from django.contrib.auth.forms import AuthenticationForm
from django.forms import modelformset_factory, inlineformset_factory
from django.contrib.auth import authenticate

# class CompanyForm(forms.ModelForm):
#     class Meta:
#         model = Company
#         fields = '__all__'


class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'contact_no', 'designation']
        widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control', 'required': True, 'maxlength': 50}),
            'email': forms.EmailInput(attrs={'class': 'form-control', 'required': True, 'maxlength': 100}),
            'contact_no': forms.TextInput(attrs={'class': 'form-control', 'required': True, 'maxlength': 15}),
            'designation': forms.TextInput(attrs={'class': 'form-control', 'required': True, 'maxlength': 100}),
        }

class ForgotPasswordForm(forms.Form):
    email = forms.EmailField()

class ResetPasswordForm(forms.Form):
    new_password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super().clean()
        p1 = cleaned_data.get("new_password")
        p2 = cleaned_data.get("confirm_password")
        if p1 != p2:
            raise forms.ValidationError("Passwords do not match.")
        return cleaned_data

# class CustomLoginForm(AuthenticationForm):
#     username = forms.EmailField(
#         widget=forms.EmailInput(attrs={
#             'class': 'form-control',
#             'placeholder': 'Enter your email',
#             'id': 'id_username'
#         }),
#         label="Email"
#     )
#     password = forms.CharField(
#         widget=forms.PasswordInput(attrs={
#             'class': 'form-control',
#             'placeholder': 'Enter your password',
#             'id': 'id_password'
#         }),
#         label="Password"
#     )


class CustomLoginForm(forms.Form):
    email = forms.EmailField(label="Email", widget=forms.EmailInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter your email'
    }))
    password = forms.CharField(label="Password", widget=forms.PasswordInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter your password',
        'id': 'id_password'
    }))

    def clean(self):
        cleaned_data = super().clean()
        email = cleaned_data.get('email')
        password = cleaned_data.get('password')

        if email and password:
            user = authenticate(email=email, password=password)
            if not user:
                raise forms.ValidationError("Invalid email or password.")
            cleaned_data['user'] = user
        return cleaned_data


class OTPVerificationForm(forms.Form):
    otp = forms.CharField(label="OTP", max_length=6, widget=forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter OTP'
    }))

class RegisterForm(forms.ModelForm):
    password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control'}))
    password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control'}))

    class Meta:
        model = User
        fields = ['username', 'email']

    def clean(self):
        cleaned_data = super().clean()
        if cleaned_data.get('password1') != cleaned_data.get('password2'):
            raise forms.ValidationError("Passwords do not match")
        return cleaned_data

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data['password1'])
        if commit:
            user.save()
        return user
    

class UserCreateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'contact_no', 'designation', 'password']
        # fields = ['username', 'email', 'first_name', 'last_name', 'password']


# class UserUpdateForm(forms.ModelForm):
#     class Meta:
#         model = User
#         fields = ['username', 'email', 'contact_no', 'designation', 'is_active']
#         error_messages = {
#             "email": {
#                 "unique": "User with this Email already exists."  # override the default
#             }
#         }

#     # def __init__(self, *args, **kwargs):
#     #     super().__init__(*args, **kwargs)
#     #     self.instance_id = self.instance.pk if self.instance else None

#     # def clean_email(self):
#     #     email = self.cleaned_data.get("email")
#     #     if email and User.objects.exclude(pk=self.instance.pk).filter(email=email).exists():
#     #         raise forms.ValidationError("User with this Email already exists.")
#     #     return email


#     def clean_email(self):
#         email = self.cleaned_data.get('email')
#         if not email:
#             return email
#         qs = User.objects.filter(email=email).exclude(pk=self.instance.pk)
#         if qs.exists():
#             raise forms.ValidationError("User with this Email already exists.")
#         return email


class UserUpdateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ["username", "email", "contact_no", "designation", "is_active"]
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance_id = self.instance.pk if self.instance else None

    def clean_email(self):
        email = self.cleaned_data.get("email")
        if not email:
            return email
        qs = User.objects.filter(email=email).exclude(pk=self.instance.pk)
        if qs.exists():
            raise forms.ValidationError("User with this Email already exists.")
        return email
    

class CompanyForm(forms.ModelForm):
    class Meta:
        model = Company
        fields = '__all__'

    # def __init__(self, *args, **kwargs):
    #     super().__init__(*args, **kwargs)
    #     # Set initial values of None fields to ''
    #     for field_name, field in self.fields.items():
    #         if self.initial.get(field_name) is None:
    #             self.initial[field_name] = ''

CompanyFormSet = modelformset_factory(
    Company,
    form=CompanyForm,
    extra=1,  # number of blank forms shown
    can_delete=False
)
'''
class ClientForm(forms.ModelForm):
    class Meta:
        model = Client
        fields = '__all__'
        widgets = {
            'dob': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'anniversary_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'created_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'updated_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            
            'residential_country': forms.Select(attrs={'class': 'form-select select2 country'}),
            'residential_state': forms.Select(attrs={'class': 'form-select select2 state'}),
            'residential_city': forms.Select(attrs={'class': 'form-select select2 city'}),
            'residential_pincode': forms.TextInput(attrs={'class': 'form-control numbersonly'}),

            'ref_company_id': forms.Select(attrs={'class': 'form-select select2 own_company'}),
            'designation': forms.TextInput(attrs={'class': 'form-control', 'maxlength': 50}),
            'primary_company': forms.CheckboxInput(attrs={'class': 'form-check-input primary_company'}),

            'member_relation': forms.Select(attrs={'class': 'form-select select2'}),
        }

    def __init__(self, *args, **kwargs):
        super(ClientForm, self).__init__(*args, **kwargs)
        self.fields['country_code'].queryset = Countries.objects.all().order_by('country_code')
'''


class ClientForm(forms.ModelForm):
    country_code = forms.ModelChoiceField(
        queryset=Countries.objects.all(),
        label="Country Code",
        widget=forms.Select(attrs={'class': 'form-control'}),
        to_field_name="id"
    )

    class Meta:
        model = Client
        fields = '__all__'
        exclude = ['created_by', 'updated_by']

        widgets = {
            'dob': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'anniversary_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'created_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'updated_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'passport_expiry_date': forms.DateInput(attrs={'type': 'date'}),
            'client_salutation': forms.Select(attrs={'class': 'form-select'}),
            'company': forms.Select(attrs={'class': 'form-select'}),
            'country_code': forms.Select(attrs={'class': 'form-select'}),
            'gender': forms.Select(attrs={'class': 'form-select'}),
            'marital_status': forms.Select(attrs={'class': 'form-select'}),
            'reference_from': forms.Select(attrs={'class': 'form-select'}),
            'preferred_contact_method': forms.Select(attrs={'class': 'form-select'}),
            'residential_city': forms.Select(attrs={'class': 'form-select'}),
            'residential_state': forms.Select(attrs={'class': 'form-select'}),
            'residential_country': forms.Select(attrs={'class': 'form-select'}),
            'ref_preferred_airline_id': forms.Select(attrs={'class': 'form-select'}),
            'seat_preference': forms.Select(attrs={'class': 'form-select'}),
            'meal_preference': forms.Select(attrs={'class': 'form-select'}),
            'fare_preference': forms.Select(attrs={'class': 'form-select'}),
            'star_rating': forms.Select(attrs={'class': 'form-select'}),
            'stay_preference': forms.Select(attrs={'class': 'form-select'}),
            'room_preference': forms.Select(attrs={'class': 'form-select'}),
            'ref_frequent_airline': forms.Select(attrs={'class': 'form-select'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Only set queryset/labels if the field exists (it won't if excluded in Meta)
        if 'created_by' in self.fields:
            self.fields['created_by'].queryset = User.objects.order_by('email')
            self.fields['created_by'].label_from_instance = lambda obj: obj.email

        if 'updated_by' in self.fields:
            self.fields['updated_by'].queryset = User.objects.order_by('email')
            self.fields['updated_by'].label_from_instance = lambda obj: obj.email

        if 'country_code' in self.fields:
            self.fields['country_code'].label_from_instance = (
                lambda obj: f"+{obj.country_code} ({obj.name})"
            )

        if 'is_active' in self.fields:
            self.fields['is_active'].widget.attrs.update({'class': 'form-check-input'})

    def clean_contact_number(self):
        contact_number = self.cleaned_data.get('contact_number')
        country = self.cleaned_data.get('country_code')

        if country:
            min_len = country.min_length or 0
            max_len = country.max_length or 0

            if min_len and len(contact_number) < min_len:
                raise forms.ValidationError(
                    f"Contact number must be at least {min_len} digits for {country.name}."
                )
            if max_len and len(contact_number) > max_len:
                raise forms.ValidationError(
                    f"Contact number cannot exceed {max_len} digits for {country.name}."
                )

        return contact_number


'''
class ClientForm(forms.ModelForm):
    country_code = forms.ModelChoiceField(
        queryset=Countries.objects.all(),
        label="Country Code",
        widget=forms.Select(attrs={'class': 'form-control'}),
        to_field_name="id"
    )
    class Meta:
        model = Client
        fields = [
            'client_code',
            'salutation',
            'first_name',
            'middle_name',
            'last_name',
            'country_code',
            'contact_number'
        ]
    class Meta:
        model = Client
        fields = '__all__'  # or list fields explicitly
        exclude = ['created_by', 'updated_by']
    

        widgets = {
            # Date/datetime inputs:
            'dob': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'anniversary_date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'created_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'updated_at': forms.DateTimeInput(attrs={'type': 'datetime-local', 'class': 'form-control'}),
            'passport_expiry_date': forms.DateInput(attrs={'type': 'date'}),

            # 'designation': forms.TextInput(attrs={'class': 'form-control'}),

            # Select inputs:
            'client_salutation': forms.Select(attrs={'class': 'form-select'}),
            'company': forms.Select(attrs={'class': 'form-select'}),
            'country_code': forms.Select(attrs={'class': 'form-select'}),
            'gender': forms.Select(attrs={'class': 'form-select'}),
            'marital_status': forms.Select(attrs={'class': 'form-select'}),
            'reference_from': forms.Select(attrs={'class': 'form-select'}),
            'preferred_contact_method': forms.Select(attrs={'class': 'form-select'}),
            'residential_city': forms.Select(attrs={'class': 'form-select'}),
            'residential_state': forms.Select(attrs={'class': 'form-select'}),
            'residential_country': forms.Select(attrs={'class': 'form-select'}),
            'ref_preferred_airline_id': forms.Select(attrs={'class': 'form-select'}),
            'seat_preference': forms.Select(attrs={'class': 'form-select'}),
            'meal_preference': forms.Select(attrs={'class': 'form-select'}),
            'fare_preference': forms.Select(attrs={'class': 'form-select'}),
            'star_rating': forms.Select(attrs={'class': 'form-select'}),
            'stay_preference': forms.Select(attrs={'class': 'form-select'}),
            'room_preference': forms.Select(attrs={'class': 'form-select'}),
            # 'client_status': forms.Select(attrs={'class': 'form-select'}),
            # 'created_by': forms.Select(attrs={'class': 'form-select'}),
            # 'updated_by': forms.Select(attrs={'class': 'form-select'}),
            'client_salutation': forms.Select(attrs={'class': 'form-select'}),
            'ref_frequent_airline': forms.Select(attrs={'class': 'form-select'}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Customize queryset for company select: show company_name as label
        # self.fields['company'].queryset = Company.objects.order_by('company_name')
        # self.fields['company'].label_from_instance = lambda obj: obj.company_name

        # Customize label for created_by and updated_by selects (User emails)
        self.fields['created_by'].queryset = User.objects.order_by('email')
        self.fields['created_by'].label_from_instance = lambda obj: obj.email

        self.fields['updated_by'].queryset = User.objects.order_by('email')
        self.fields['updated_by'].label_from_instance = lambda obj: obj.email

        self.fields['country_code'].label_from_instance = (
            lambda obj: f"+{obj.country_code} ({obj.name})"
        )

        # self.fields['designation'].widget = forms.TextInput(attrs={'class': 'form-control'})

        # Allow null fields where applicable by making fields not required
        # for field_name in ['client_status', 'created_at', 'created_by', 'updated_at', 'updated_by', 'company']:
        #     if field_name in self.fields:
        #         self.fields[field_name].required = False
        #         self.fields['designation'].required = False

        # For BooleanField (is_active), show as checkbox
        self.fields['is_active'].widget.attrs.update({'class': 'form-check-input'})
    
    def clean_contact_number(self):
        contact_number = self.cleaned_data.get('contact_number')
        country = self.cleaned_data.get('country_code')

        if country:
            min_len = country.min_length or 0
            max_len = country.max_length or 0

            if min_len and len(contact_number) < min_len:
                raise forms.ValidationError(
                    f"Contact number must be at least {min_len} digits for {country.name}."
                )
            if max_len and len(contact_number) > max_len:
                raise forms.ValidationError(
                    f"Contact number cannot exceed {max_len} digits for {country.name}."
                )

        return contact_number
'''


class FrequentFlyerForm(forms.ModelForm):
    class Meta:
        model = ClientFrequentFlyer
        fields = ['ref_airline', 'ff_no', 'ref_client']
        widgets = {
            'ref_airline': forms.Select(attrs={'class': 'form-select'}),
            'ff_no': forms.TextInput(attrs={'class': 'form-control'}),
        }
        labels = {
            'ref_airline': 'Airlines',
            'ff_no': 'FF No.',
        }

    def save(self, commit=True):
        instance = super().save(commit=False)
        # instance.ref_airline_id = self.cleaned_data['airline']
        if 'airline' in self.cleaned_data:
            airline = self.cleaned_data['airline']
        else:
            airline = None
        if commit:
            instance.save()
        return instance


class ClientPassportForm(forms.ModelForm):
    class Meta:
        model = ClientPassport
        fields = ["passport_file", "passport_no", "passport_expiry_date", "ref_client"]
        widgets = {
            "passport_no": forms.TextInput(attrs={
                "class": "form-control alpha_numeric valid_pspt",
                "maxlength": "10",
                "onkeyup": "this.value = this.value.toUpperCase();"
            }),
            "passport_expiry_date": forms.DateInput(attrs={
                "type": "date",
                "class": "form-control datetimepicker",
                "data-options": '{"dateFormat":"d/m/Y", "disableMobile":true}'
            }),
            "passport_file": forms.FileInput(attrs={
                "class": "form-control",
                "accept": "image/jpg,image/jpeg,image/png,application/pdf"
            }),
        }

PassportFormSet = inlineformset_factory(
    Client,
    ClientPassport,
    form=ClientPassportForm,
    extra=1,          # Show one blank form by default
    can_delete=True   # Allow deleting passports
)


class AssocClientCompanyForm(forms.ModelForm):
    class Meta:
        model = AssocClientCompany
        fields = ["ref_company", "designation", "primary_company", "ref_client"]
        widgets = {
            "ref_company": forms.Select(attrs={
                "class": "form-control select2",  # if you use Select2
            }),
            "designation": forms.TextInput(attrs={
                "class": "form-control alpha_numeric",
                "maxlength": "50",
            }),
            "primary_company": forms.CheckboxInput(attrs={
                "class": "form-check-input",
            }),
            "ref_client": forms.HiddenInput(),  # usually hidden since it's bound from parent
        }

# Create formset using the custom form
AssocClientCompanyFormSet = inlineformset_factory(
    Client,
    AssocClientCompany,
    form=AssocClientCompanyForm,  # use your custom form
    extra=1,
    can_delete=True,
)
# AssocClientCompanyForm = inlineformset_factory(
#     Client,
#     AssocClientCompany,
#     fields=['ref_company_id', 'designation', 'primary_company', 'ref_client_id'],
#     extra=1,
#     can_delete=True,
# )


class OtherDocumentForm(forms.ModelForm):
    class Meta:
        model = ClientDocument
        fields = ["other_document", "other_document_name", "ref_client"]
        widgets = {
            "document_type": forms.Select(attrs={
                "class": "form-select select2",
                "data-placeholder": "-- Select Document Type --"
            }),
            "document_file": forms.FileInput(attrs={
                "class": "form-control",
                "accept": "image/jpg,image/jpeg,image/png,application/pdf"
            }),
        }

# Optional: if you want multiple document uploads in one go
OtherDocumentFormSet = inlineformset_factory(
    Client,
    ClientDocument,
    form=OtherDocumentForm,
    extra=1,          # Show one blank form by default
    can_delete=True   # Allow deleting documents
)


class ClientVisaForm(forms.ModelForm):
    class Meta:
        model = ClientVisa
        fields = [
            'ref_visa_country',
            'visa_type',
            'passport_size_photograph',
            'visa_from_date',
            'visa_to_date',
        ]
        widgets = {
            # 'ref_visa_country': forms.Select(attrs={'class': 'form-select'}),
            'ref_visa_country': forms.Select(attrs={'class': 'form-select'}),
            'visa_type': forms.Select(attrs={'class': 'form-select'}),
            'passport_size_photograph': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/jpg,image/jpeg,image/png,application/pdf'
            }),
            'visa_from_date': forms.DateInput(attrs={
                'class': 'form-control datetimepicker',
                'type': 'date',
                'data-options': '{"dateFormat":"d/m/Y", "disableMobile":true}'
            }),
            'visa_to_date': forms.DateInput(attrs={
                'class': 'form-control datetimepicker',
                'type': 'date',
                'data-options': '{"dateFormat":"d/m/Y", "disableMobile":true}'
            }),
        }

VisaFormSet = inlineformset_factory(
    Client,
    ClientVisa,
    form=ClientVisaForm,
    extra=1,
    can_delete=True
)


class ClientTravelInsuranceForm(forms.ModelForm):
    class Meta:
        model = ClientTravelInsurance
        fields = ['insurance_document', 'insurance_from_date', 'insurance_to_date', 'ref_client']
        widgets = {
            'insurance_document': forms.FileInput(attrs={
                'class': 'form-control',
                'accept': 'image/jpg,image/jpeg,image/png,application/pdf'
            }),
            'insurance_from_date': forms.DateInput(attrs={
                'class': 'form-control datetimepicker',
                'type': 'date',
                'data-options': '{"dateFormat":"d/m/Y", "disableMobile":true}'
            }),
            'insurance_to_date': forms.DateInput(attrs={
                'class': 'form-control datetimepicker',
                'type': 'date',
                'data-options': '{"dateFormat":"d/m/Y", "disableMobile":true}'
            }),
        }

TravelInsuranceFormSet = inlineformset_factory(
    Client,
    ClientTravelInsurance,
    form=ClientTravelInsuranceForm,
    extra=1,
    can_delete=True
)

# class ClientForm(forms.ModelForm):
#     class Meta:
#         model = Client
#         fields = '__all__'
#         widgets = {
#             'dob': forms.DateInput(attrs={'type': 'date'}),
#         }