from django import forms
from django.contrib.auth.forms import PasswordChangeForm, PasswordResetForm
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from .models import HostProfile, HostEventPackage
from .models import (
    HostVenue, 
    HostVenueImage, 
    HostMealPlan, 
    HostAddOnService, 
    HostBankingDetails,
    HostingClientProfile,
)

class HostingClientProfileForm(forms.ModelForm):
    class Meta:
        model = HostingClientProfile
        fields = [
            'full_name',
            'email',
            'phone_number',
            'whatsapp_number',
            'country',
            'city',
        ]

        widgets = {
            'full_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Full name',
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'Email address',
            }),
            'phone_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Phone number',
            }),
            'whatsapp_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'WhatsApp number',
            }),
            'country': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Country',
            }),
            'city': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'City',
            }),
        }


class HostingClientProfileImageForm(forms.ModelForm):
    class Meta:
        model = HostingClientProfile
        fields = ['profile_image']


class HostingClientUsernameChangeForm(forms.Form):
    username = forms.CharField(
        max_length=150,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'New username',
        })
    )

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

    def clean_username(self):
        username = self.cleaned_data['username'].strip()

        if User.objects.exclude(pk=self.user.pk).filter(username=username).exists():
            raise forms.ValidationError(
                "This username is already taken. Please choose another one."
            )

        return username

    def save(self):
        self.user.username = self.cleaned_data['username'].strip()
        self.user.save()
        return self.user


class StyledHostingClientPasswordChangeForm(PasswordChangeForm):
    old_password = forms.CharField(
        label="Current password",
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Current password',
        })
    )

    new_password1 = forms.CharField(
        label="New password",
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'New password',
        })
    )

    new_password2 = forms.CharField(
        label="Confirm new password",
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Confirm new password',
        })
    )

class HostPasswordResetForm(PasswordResetForm):
    """
    Only allows password reset emails for active users
    who have a HostProfile.
    """

    def get_users(self, email):
        active_users = super().get_users(email)

        for user in active_users:
            if hasattr(user, 'host_profile'):
                yield user

class HostingClientPasswordResetForm(PasswordResetForm):
    """
    Only allows password reset emails for active users
    who have a HostingClientProfile.
    """

    def get_users(self, email):
        active_users = super().get_users(email)

        for user in active_users:
            if hasattr(user, 'hosting_client_profile'):
                yield user

class HostSignupForm(forms.ModelForm):
    class Meta:
        model = HostProfile
        fields = [
            'business_name',
            'contact_person_name',
            'email',
            'phone_number',
            'whatsapp_number',
            'profile_image',
            'short_introduction',
        ]

        widgets = {
            'business_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Business or venue owner name'
            }),
            'contact_person_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Contact person full name'
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'Email address'
            }),
            'phone_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Phone number'
            }),
            'whatsapp_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'WhatsApp number, if different'
            }),
            'profile_image': forms.ClearableFileInput(attrs={
                'class': 'form-control'
            }),
            'short_introduction': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Briefly introduce your hosting business, venue experience, or services.'
            }),
        }

        labels = {
            'business_name': 'Business Name',
            'contact_person_name': 'Contact Person Name',
            'email': 'Email Address',
            'phone_number': 'Phone Number',
            'whatsapp_number': 'WhatsApp Number',
            'profile_image': 'Profile Image',
            'short_introduction': 'Short Introduction',
        }

    def clean_email(self):
        email = self.cleaned_data.get('email', '').strip().lower()
        return email
    
class HostProfileForm(forms.ModelForm):
    class Meta:
        model = HostProfile
        fields = [
            'business_name',
            'contact_person_name',
            'email',
            'phone_number',
            'whatsapp_number',
            'short_introduction',
        ]

        widgets = {
            'business_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Business name'
            }),
            'contact_person_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Contact person name'
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'Email address'
            }),
            'phone_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Phone number'
            }),
            'whatsapp_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'WhatsApp number'
            }),
            'short_introduction': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 5,
                'placeholder': 'Brief introduction about your hosting business or venue experience.'
            }),
        }

        labels = {
            'business_name': 'Business Name',
            'contact_person_name': 'Contact Person Name',
            'email': 'Email Address',
            'phone_number': 'Phone Number',
            'whatsapp_number': 'WhatsApp Number',
            'short_introduction': 'Short Introduction',
        }

    def clean_email(self):
        email = self.cleaned_data.get('email', '').strip().lower()

        host = self.instance

        existing_user = User.objects.filter(
            email__iexact=email
        ).exclude(pk=host.user_id).first()

        if existing_user:
            raise ValidationError(
                "Another account already exists with this email address."
            )

        return email
    
class HostProfileImageForm(forms.ModelForm):
    class Meta:
        model = HostProfile
        fields = ['profile_image']

class HostUsernameChangeForm(forms.Form):
    new_username = forms.CharField(
        max_length=150,
        label='New Username',
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter a new username'
        })
    )

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

        if not self.is_bound:
            self.fields['new_username'].initial = user.username

    def clean_new_username(self):
        new_username = self.cleaned_data.get('new_username', '').strip()

        if not new_username:
            raise ValidationError("Username cannot be empty.")

        if User.objects.filter(
            username__iexact=new_username
        ).exclude(pk=self.user.pk).exists():
            raise ValidationError(
                "This username is already taken. Please choose another one."
            )

        return new_username

    def save(self):
        self.user.username = self.cleaned_data['new_username']
        self.user.save(update_fields=['username'])
        return self.user
    
class StyledHostPasswordChangeForm(PasswordChangeForm):
    old_password = forms.CharField(
        label="Current Password",
        strip=False,
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter your current password',
            'autocomplete': 'current-password',
        }),
    )

    new_password1 = forms.CharField(
        label="New Password",
        strip=False,
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Enter a new password',
            'autocomplete': 'new-password',
        }),
        help_text=PasswordChangeForm.base_fields['new_password1'].help_text,
    )

    new_password2 = forms.CharField(
        label="Confirm New Password",
        strip=False,
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': 'Confirm your new password',
            'autocomplete': 'new-password',
        }),
    )

# ============================================================
# Host Venue Forms
# ============================================================

class HostVenueForm(forms.ModelForm):
    """
    Host-side venue form.

    Important:
    We use fields='__all__' and remove admin/system fields dynamically.
    This makes the form safer while your HostVenue model is still evolving.
    """

    class Meta:
        model = HostVenue
        fields = '__all__'

    HOST_HIDDEN_FIELDS = {
        'host_profile',
        'slug',
        'listing_status',
        'is_featured',
        'admin_review_note',
        'approved_at',
        'created_at',
        'updated_at',
    }

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

        # Remove fields that hosts should not control directly
        for field_name in list(self.fields.keys()):
            if field_name in self.HOST_HIDDEN_FIELDS:
                self.fields.pop(field_name)

        # Apply Bootstrap / premium-friendly classes
        for field_name, field in self.fields.items():
            widget = field.widget

            if isinstance(widget, forms.CheckboxInput):
                widget.attrs.update({
                    'class': 'form-check-input'
                })

            elif isinstance(widget, forms.Textarea):
                widget.attrs.update({
                    'class': 'form-control',
                    'rows': 4,
                    'placeholder': field.label,
                })

            elif isinstance(widget, forms.Select):
                widget.attrs.update({
                    'class': 'form-select',
                })

            elif isinstance(widget, forms.ClearableFileInput):
                widget.attrs.update({
                    'class': 'form-control',
                })

            else:
                widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': field.label,
                })


class HostVenueImageForm(forms.ModelForm):
    """
    Host-side gallery image upload form.
    Validation and compression should already happen in the model or image utilities.
    """

    class Meta:
        model = HostVenueImage
        fields = [
            'image',
            'caption',
            'display_order',
        ]

        widgets = {
            'image': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/*',
            }),
            'caption': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Optional image caption',
            }),
            'display_order': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': 0,
            }),
        }

# ============================================================
# Host Event Package Form
# ============================================================

class HostEventPackageForm(forms.ModelForm):
    """
    Host-side event package form.

    Hosts can create packages for their own approved/created venues.
    Admin/system fields are hidden from the host form.
    """

    class Meta:
        model = HostEventPackage
        fields = '__all__'

    HOST_HIDDEN_FIELDS = {
        'slug',
        'listing_status',
        'is_active',
        'is_featured',
        'admin_review_note',
        'approved_at',
        'created_at',
        'updated_at',
    }

    def __init__(self, *args, **kwargs):
        host_profile = kwargs.pop('host_profile', None)
        selected_venue = kwargs.pop('selected_venue', None)

        super().__init__(*args, **kwargs)

        for field_name in list(self.fields.keys()):
            if field_name in self.HOST_HIDDEN_FIELDS:
                self.fields.pop(field_name)

        # Only show venues belonging to this host.
        if 'venue' in self.fields and host_profile is not None:
            self.fields['venue'].queryset = HostVenue.objects.filter(
                host_profile=host_profile
            ).order_by('venue_name')

        # If creating from a specific venue, preselect and hide venue.
        if selected_venue is not None and 'venue' in self.fields:
            self.fields['venue'].initial = selected_venue
            self.fields['venue'].widget = forms.HiddenInput()

        if 'event_type' in self.fields:
            self.fields['event_type'].empty_label = "Select Event Type"

        if 'venue' in self.fields and not isinstance(self.fields['venue'].widget, forms.HiddenInput):
            self.fields['venue'].empty_label = "Select Venue"

        for field_name, field in self.fields.items():
            widget = field.widget

            if isinstance(widget, forms.CheckboxInput):
                widget.attrs.update({
                    'class': 'form-check-input'
                })

            elif isinstance(widget, forms.Textarea):
                widget.attrs.update({
                    'class': 'form-control',
                    'rows': 4,
                    'placeholder': field.label,
                })

            elif isinstance(widget, forms.Select):
                widget.attrs.update({
                    'class': 'form-select',
                })

            elif isinstance(widget, forms.ClearableFileInput):
                widget.attrs.update({
                    'class': 'form-control',
                    'accept': 'image/*',
                })

            elif isinstance(widget, forms.HiddenInput):
                pass

            else:
                widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': field.label,
                })

# ============================================================
# Host Meal Plan Form
# ============================================================

class HostMealPlanForm(forms.ModelForm):
    """
    Host-side meal plan form.

    Hosts can create meal plans for their own venues.
    Admin/system fields are hidden from the host form.
    """

    class Meta:
        model = HostMealPlan
        fields = '__all__'

    HOST_HIDDEN_FIELDS = {
        'listing_status',
        'is_active',
        'is_featured',
        'admin_review_note',
        'approved_at',
        'created_at',
        'updated_at',
    }

    def __init__(self, *args, **kwargs):
        host_profile = kwargs.pop('host_profile', None)
        selected_venue = kwargs.pop('selected_venue', None)

        super().__init__(*args, **kwargs)

        for field_name in list(self.fields.keys()):
            if field_name in self.HOST_HIDDEN_FIELDS:
                self.fields.pop(field_name)

        # Only show venues owned by this host.
        if 'venue' in self.fields and host_profile is not None:
            self.fields['venue'].queryset = HostVenue.objects.filter(
                host_profile=host_profile
            ).order_by('venue_name')

        # If creating from a selected venue, hide the venue field.
        if selected_venue is not None and 'venue' in self.fields:
            self.fields['venue'].initial = selected_venue
            self.fields['venue'].widget = forms.HiddenInput()

        if 'venue' in self.fields and not isinstance(self.fields['venue'].widget, forms.HiddenInput):
            self.fields['venue'].empty_label = "Select Venue"

        for field_name, field in self.fields.items():
            widget = field.widget

            if isinstance(widget, forms.CheckboxInput):
                widget.attrs.update({
                    'class': 'form-check-input'
                })

            elif isinstance(widget, forms.Textarea):
                widget.attrs.update({
                    'class': 'form-control',
                    'rows': 4,
                    'placeholder': field.label,
                })

            elif isinstance(widget, forms.Select):
                widget.attrs.update({
                    'class': 'form-select',
                })

            elif isinstance(widget, forms.ClearableFileInput):
                widget.attrs.update({
                    'class': 'form-control',
                    'accept': 'image/*',
                })

            elif isinstance(widget, forms.HiddenInput):
                pass

            else:
                widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': field.label,
                })

# ============================================================
# Host Add-on Service Form
# ============================================================

class HostAddOnServiceForm(forms.ModelForm):
    """
    Host-side add-on service form.

    Hosts can create optional services for their own venues.
    Admin/system fields are hidden from the host form.
    """

    class Meta:
        model = HostAddOnService
        fields = '__all__'

    HOST_HIDDEN_FIELDS = {
        'listing_status',
        'is_active',
        'is_featured',
        'admin_review_note',
        'approved_at',
        'created_at',
        'updated_at',
    }

    def __init__(self, *args, **kwargs):
        host_profile = kwargs.pop('host_profile', None)
        selected_venue = kwargs.pop('selected_venue', None)

        super().__init__(*args, **kwargs)

        for field_name in list(self.fields.keys()):
            if field_name in self.HOST_HIDDEN_FIELDS:
                self.fields.pop(field_name)

        if 'venue' in self.fields and host_profile is not None:
            self.fields['venue'].queryset = HostVenue.objects.filter(
                host_profile=host_profile
            ).order_by('venue_name')

        if selected_venue is not None and 'venue' in self.fields:
            self.fields['venue'].initial = selected_venue
            self.fields['venue'].widget = forms.HiddenInput()

        if 'venue' in self.fields and not isinstance(self.fields['venue'].widget, forms.HiddenInput):
            self.fields['venue'].empty_label = "Select Venue"

        if 'pricing_type' in self.fields:
            self.fields['pricing_type'].empty_label = "Select Pricing Type"

        for field_name, field in self.fields.items():
            widget = field.widget

            if isinstance(widget, forms.CheckboxInput):
                widget.attrs.update({'class': 'form-check-input'})

            elif isinstance(widget, forms.Textarea):
                widget.attrs.update({
                    'class': 'form-control',
                    'rows': 4,
                    'placeholder': field.label,
                })

            elif isinstance(widget, forms.Select):
                widget.attrs.update({'class': 'form-select'})

            elif isinstance(widget, forms.ClearableFileInput):
                widget.attrs.update({
                    'class': 'form-control',
                    'accept': 'image/*',
                })

            elif isinstance(widget, forms.HiddenInput):
                pass

            else:
                widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': field.label,
                })

# ============================================================
# Host Banking Details Form
# ============================================================

class HostBankingDetailsForm(forms.ModelForm):
    class Meta:
        model = HostBankingDetails
        fields = [
            'account_holder_name',
            'bank_name',
            'branch_name',
            'account_number',
            'iban',
            'swift_code',
            'bank_country',
            'bank_address',
            'payment_notes',
        ]

        widgets = {
            'account_holder_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Account holder name',
            }),
            'bank_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Bank name',
            }),
            'branch_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Branch name',
            }),
            'account_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Account number',
            }),
            'iban': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'IBAN, if applicable',
            }),
            'swift_code': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'SWIFT / BIC code, if applicable',
            }),
            'bank_country': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Bank country',
            }),
            'bank_address': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Bank address, if applicable',
            }),
            'payment_notes': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Optional payout notes or preferred instructions',
            }),
        }

class HostingClientSignupForm(forms.Form):
    full_name = forms.CharField(
        max_length=255,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Your full name',
        })
    )

    email = forms.EmailField(
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': 'Your email address',
        })
    )

    phone_number = forms.CharField(
        max_length=50,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Phone number',
        })
    )

    whatsapp_number = forms.CharField(
        max_length=50,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'WhatsApp number optional',
        })
    )

    country = forms.CharField(
        max_length=120,
        initial='Sri Lanka',
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Country',
        })
    )

    city = forms.CharField(
        max_length=120,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'City',
        })
    )