from django import forms
from .models import (
    PropertyManagerClientProfile,
    ManagedProperty,
    ManagedPropertyImage,
    ManagedPropertyDocument,
)


from django.contrib.auth import get_user_model
from django.contrib.auth.forms import PasswordResetForm

from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError

User = get_user_model()


class PropertyManagerProfileForm(forms.ModelForm):
    class Meta:
        model = PropertyManagerClientProfile

        fields = [
            'client_type',
            'residency_status',
            'full_name',
            'email',
            'whatsapp_number',
            'phone_number',
            'current_country',
            'current_city',
            'emergency_contact_name',
            'emergency_contact_phone',
            'short_note',
        ]

        widgets = {
            'client_type': forms.Select(attrs={
                'class': 'form-select',
            }),

            'residency_status': forms.Select(attrs={
                'class': 'form-select',
            }),

            'full_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter your full name',
            }),

            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter your email address',
            }),

            'whatsapp_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'WhatsApp number',
            }),

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

            'current_country': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Country where you currently live',
            }),

            'current_city': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Current city',
            }),

            'emergency_contact_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Emergency contact person',
            }),

            'emergency_contact_phone': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Emergency contact phone number',
            }),

            'short_note': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Optional note about your situation or property care expectations.',
            }),
        }

        labels = {
            'client_type': 'Owner / Client Type',
            'residency_status': 'Residency Status',
            'full_name': 'Full Name',
            'email': 'Email Address',
            'whatsapp_number': 'WhatsApp Number',
            'phone_number': 'Phone Number',
            'current_country': 'Current Country',
            'current_city': 'Current City',
            'emergency_contact_name': 'Emergency Contact Name',
            'emergency_contact_phone': 'Emergency Contact Phone',
            'short_note': 'Short Note',
        }

class PropertyManagerProfileImageForm(forms.ModelForm):
    class Meta:
        model = PropertyManagerClientProfile

        fields = [
            'profile_image',
        ]

        widgets = {
            'profile_image': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/jpeg,image/jpg,image/png,image/webp',
            }),
        }

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

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

        self.fields['username'].initial = user.username

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

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

        username_exists = User.objects.filter(
            username__iexact=username
        ).exclude(
            pk=self.user.pk
        ).exists()

        if username_exists:
            raise ValidationError(
                "This username is already in use. Please choose another one."
            )

        return username

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

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

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

class ManagedPropertyImageForm(forms.ModelForm):
    """
    Form for adding a single visual reference image
    to a registered managed property.
    """

    class Meta:
        model = ManagedPropertyImage

        fields = [
            'image',
            'caption',
        ]

        widgets = {
            'image': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': 'image/*',
            }),

            'caption': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Optional: Front view, garden, living room, boundary wall, etc.'
            }),
        }

        labels = {
            'image': 'Property Image',
            'caption': 'Image Caption',
        }

        help_texts = {
            'image': 'Upload a clear image that helps us understand the property and its current condition.',
            'caption': 'Optional, but useful for identifying what the image shows.',
        }


class ManagedPropertyForm(forms.ModelForm):
    """
    Form used by Property Care Owners to register properties
    that may later be reviewed, estimated, and assigned
    a maintenance/service plan.
    """

    class Meta:
        model = ManagedProperty

        fields = [
            # Property identity
            'property_name',
            'property_category',
            'occupancy_status',

            # Location
            'city',
            'district',
            'address',
            'google_map_link',

            # Land details
            'land_size',
            'land_size_unit',

            # Building scale
            'number_of_buildings',
            'total_floor_area',
            'floor_area_unit',
            'number_of_storeys',
            'bedrooms',
            'bathrooms',
            'kitchens',
            'living_rooms',
            'other_rooms',

            # Condition
            'property_age',
            'current_condition',

            # Exterior / access
            'has_boundary_wall_or_fence',
            'has_gate',
            'has_garden_or_landscape',
            'needs_grass_cutting',

            # Utilities
            'electricity_active',
            'water_active',
            'internet_active',

            # Access permissions
            'needs_key_holding_service',
            'allows_emergency_access',

            # Notes
            'owner_notes',
        ]

        widgets = {
            # Property identity
            'property_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Example: My family home in Kandy'
            }),

            'property_category': forms.Select(attrs={
                'class': 'form-select'
            }),

            'occupancy_status': forms.Select(attrs={
                'class': 'form-select'
            }),

            # Location
            'city': forms.Select(attrs={
                'class': 'form-select'
            }),

            'district': forms.Select(attrs={
                'class': 'form-select'
            }),

            'address': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 3,
                'placeholder': 'Enter the property address or clear location description'
            }),

            'google_map_link': forms.URLInput(attrs={
                'class': 'form-control',
                'placeholder': 'Optional Google Maps location link'
            }),

            # Land details
            'land_size': forms.NumberInput(attrs={
                'class': 'form-control',
                'placeholder': 'Example: 40',
                'step': '0.01',
                'min': '0'
            }),

            'land_size_unit': forms.Select(attrs={
                'class': 'form-select'
            }),

            # Building details
            'number_of_buildings': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'total_floor_area': forms.NumberInput(attrs={
                'class': 'form-control',
                'placeholder': 'Example: 2000',
                'step': '0.01',
                'min': '0'
            }),

            'floor_area_unit': forms.Select(attrs={
                'class': 'form-select'
            }),

            'number_of_storeys': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'bedrooms': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'bathrooms': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'kitchens': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'living_rooms': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            'other_rooms': forms.NumberInput(attrs={
                'class': 'form-control',
                'min': '0'
            }),

            # Condition
            'property_age': forms.Select(attrs={
                'class': 'form-select'
            }),

            'current_condition': forms.Select(attrs={
                'class': 'form-select'
            }),

            # Notes
            'owner_notes': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 5,
                'placeholder': (
                    'Tell us anything important about access, current issues, '
                    'special instructions, concerns, or your expected support.'
                )
            }),

            # Boolean / checkbox widgets
            'has_boundary_wall_or_fence': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'has_gate': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'has_garden_or_landscape': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'needs_grass_cutting': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'electricity_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'water_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'internet_active': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'needs_key_holding_service': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
            'allows_emergency_access': forms.CheckboxInput(attrs={
                'class': 'form-check-input'
            }),
        }

        labels = {
            'property_name': 'Property Name / Nickname',
            'property_category': 'Property Type',
            'occupancy_status': 'Current Occupancy Status',

            'city': 'Nearest City',
            'district': 'District',
            'address': 'Property Address / Location Description',
            'google_map_link': 'Google Maps Link',

            'land_size': 'Land Size',
            'land_size_unit': 'Land Size Unit',

            'number_of_buildings': 'Number of Buildings',
            'total_floor_area': 'Total Floor Area',
            'floor_area_unit': 'Floor Area Unit',
            'number_of_storeys': 'Number of Storeys',
            'bedrooms': 'Bedrooms',
            'bathrooms': 'Bathrooms / Washrooms',
            'kitchens': 'Kitchens',
            'living_rooms': 'Living Rooms',
            'other_rooms': 'Other Rooms',

            'property_age': 'Approximate Property Age',
            'current_condition': 'Current Property Condition',

            'has_boundary_wall_or_fence': 'Boundary Wall or Fence Available',
            'has_gate': 'Gate Available',
            'has_garden_or_landscape': 'Garden or Landscaped Outdoor Area',
            'needs_grass_cutting': 'Regular Grass Cutting May Be Needed',

            'electricity_active': 'Electricity Connection Active',
            'water_active': 'Water Connection Active',
            'internet_active': 'Internet Connection Active',

            'needs_key_holding_service': 'I May Need Ensolanka Key-Holding Support',
            'allows_emergency_access': 'I May Allow Emergency Access When Authorized',

            'owner_notes': 'Owner Notes / Special Instructions',
        }

        help_texts = {
            'property_name': 'This helps you identify the property inside your dashboard.',
            'google_map_link': 'Optional but helpful for location review and future service planning.',
            'land_size': 'Use perches for smaller properties or acres for larger lands/estates.',
            'total_floor_area': 'Approximate value is acceptable at this stage.',
            'owner_notes': 'This can include current concerns, urgency, or specific maintenance expectations.',
        }

    def clean(self):
        cleaned_data = super().clean()

        property_category = cleaned_data.get('property_category')
        land_size = cleaned_data.get('land_size')
        total_floor_area = cleaned_data.get('total_floor_area')
        number_of_buildings = cleaned_data.get('number_of_buildings')

        # Land size should not be negative or zero if provided
        if land_size is not None and land_size <= 0:
            self.add_error(
                'land_size',
                'Land size must be greater than zero.'
            )

        # Floor area should not be negative or zero if provided
        if total_floor_area is not None and total_floor_area <= 0:
            self.add_error(
                'total_floor_area',
                'Total floor area must be greater than zero.'
            )

        # Vacant land should normally include land size
        if property_category == 'vacant_land' and not land_size:
            self.add_error(
                'land_size',
                'Please enter the land size for a vacant land property.'
            )

        # Building-oriented properties should usually include at least one building
        building_categories = {
            'land_with_house',
            'house',
            'villa',
            'apartment',
            'commercial_building',
            'estate',
            'mixed_property',
        }

        if property_category in building_categories and number_of_buildings == 0:
            self.add_error(
                'number_of_buildings',
                'Please enter at least 1 building for this property type.'
            )

        return cleaned_data



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

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

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

class PropertyManagerSignupForm(forms.ModelForm):
    class Meta:
        model = PropertyManagerClientProfile
        fields = [
            'client_type',
            'residency_status',
            'full_name',
            'email',
            'whatsapp_number',
            'phone_number',
            'current_country',
            'current_city',
            'emergency_contact_name',
            'emergency_contact_phone',
            'profile_image',
            'short_note',
        ]

        widgets = {
            'client_type': forms.Select(attrs={
                'class': 'form-select'
            }),
            'residency_status': forms.Select(attrs={
                'class': 'form-select'
            }),
            'full_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter your full name'
            }),
            'email': forms.EmailInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter your email address'
            }),
            'whatsapp_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'WhatsApp number'
            }),
            'phone_number': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Phone number'
            }),
            'current_country': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Country where you currently live'
            }),
            'current_city': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Current city'
            }),
            'emergency_contact_name': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Emergency contact person in Sri Lanka, if any'
            }),
            'emergency_contact_phone': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Emergency contact phone number'
            }),
            'profile_image': forms.ClearableFileInput(attrs={
                'class': 'form-control'
            }),
            'short_note': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Briefly tell us about your situation or the kind of property care support you expect.'
            }),
        }

        labels = {
            'client_type': 'You are signing up as',
            'residency_status': 'Your current situation',
            'full_name': 'Full Name',
            'email': 'Email Address',
            'whatsapp_number': 'WhatsApp Number',
            'phone_number': 'Phone Number',
            'current_country': 'Current Country',
            'current_city': 'Current City',
            'emergency_contact_name': 'Emergency Contact Name',
            'emergency_contact_phone': 'Emergency Contact Phone',
            'profile_image': 'Profile Image',
            'short_note': 'Optional Note',
        }

class ManagedPropertyDocumentForm(forms.ModelForm):
    class Meta:
        model = ManagedPropertyDocument

        fields = [
            'document_type',
            'title',
            'file',
            'description',
            'is_owner_visible',
        ]

        widgets = {
            'document_type': forms.Select(attrs={
                'class': 'form-select',
            }),

            'title': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Example: Land Survey Plan - Lot 17',
            }),

            'file': forms.ClearableFileInput(attrs={
                'class': 'form-control',
                'accept': '.pdf,.jpg,.jpeg,.png,.webp',
            }),

            'description': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 4,
                'placeholder': 'Optional note explaining what this document contains or why it is relevant.',
            }),

            'is_owner_visible': forms.CheckboxInput(attrs={
                'class': 'form-check-input',
            }),
        }

        labels = {
            'document_type': 'Document Type',
            'title': 'Document Title',
            'file': 'Upload Document',
            'description': 'Description / Note',
            'is_owner_visible': 'Keep visible in my property records',
        }

        help_texts = {
            'document_type': (
                'Choose whether this is a land plan, building plan, ownership proof, utility document, or another reference file.'
            ),
            'file': (
                'Allowed formats: PDF, JPG, JPEG, PNG, or WEBP. Maximum size follows the document validator configured in the model.'
            ),
            'is_owner_visible': (
                'This keeps the document visible within your own owner-facing property records. Staff can still review the file when required.'
            ),
        }