from django import forms
from django.contrib.auth.models import User
from .models import Voter, Interaction, Donation, VoterLikelihood, InteractionType, DonationMethod, ElectionType, Event, EventParticipation, EventType, Tenant, ParticipationStatus, Volunteer, VolunteerEvent, VolunteerRole, ScheduledCall
from core.permissions import get_user_role

class Select2MultipleWidget(forms.SelectMultiple):
    """
    Custom widget to mark fields for Select2 initialization in the template.
    """
    def __init__(self, attrs=None, choices=()):
        default_attrs = {"multiple": "multiple"}
        if attrs:
            default_attrs.update(attrs)
        super().__init__(attrs=default_attrs, choices=choices)

class VoterForm(forms.ModelForm):
    class Meta:
        model = Voter
        fields = [
            'first_name', 'last_name', 'nickname', 'birthdate', 'address_street', 'city', 'state', 'prior_state',
            'zip_code', 'county', 'neighborhood', 'latitude', 'longitude',
            'phone', 'phone_type', 'secondary_phone', 'secondary_phone_type', 'email', 'voter_id', 'district', 'precinct', 
            'registration_date', 'is_targeted', 'door_visit', 'candidate_support', 'yard_sign', 'window_sticker', 'notes'
        ]
        widgets = {
            'birthdate': forms.DateInput(attrs={'type': 'date'}),
            'registration_date': forms.DateInput(attrs={'type': 'date'}),
            'latitude': forms.TextInput(attrs={'class': 'form-control bg-light'}),
            'longitude': forms.TextInput(attrs={'class': 'form-control bg-light'}),
            'notes': forms.Textarea(attrs={'rows': 3}),
        }

    def __init__(self, *args, user=None, tenant=None, **kwargs):
        self.user = user
        self.tenant = tenant
        super().__init__(*args, **kwargs)
        # Restrict fields for non-admin users
        is_admin = False
        if user:
            if user.is_superuser:
                is_admin = True
            elif tenant:
                role = get_user_role(user, tenant)
                if role in ["admin", "system_admin", "campaign_admin"]:
                    is_admin = True

        if not is_admin:
            restricted_fields = [
                "first_name", "last_name", "voter_id", "district", "precinct", 
                "registration_date", "address_street", "city", "state", "zip_code"
            ]
            for field_name in restricted_fields:
                if field_name in self.fields:
                    self.fields[field_name].widget.attrs["readonly"] = True
                    self.fields[field_name].widget.attrs["class"] = self.fields[field_name].widget.attrs.get("class", "") + " bg-light"

        for name, field in self.fields.items():
            if name in ['latitude', 'longitude']:
                continue
            if isinstance(field.widget, forms.CheckboxInput):
                field.widget.attrs.update({'class': 'form-check-input'})
            else:
                field.widget.attrs.update({'class': 'form-control'})
        
        self.fields['candidate_support'].widget.attrs.update({'class': 'form-select'})
        self.fields['yard_sign'].widget.attrs.update({'class': 'form-select'})
        self.fields['window_sticker'].widget.attrs.update({'class': 'form-select'})
        self.fields['phone_type'].widget.attrs.update({'class': 'form-select'})
        self.fields['secondary_phone_type'].widget.attrs.update({'class': 'form-select'})


    def clean(self):
        cleaned_data = super().clean()
        
        # Backend protection for restricted fields
        is_admin = False
        user = getattr(self, "user", None)
        tenant = getattr(self, "tenant", None)
        
        # We need to set these on the form instance if we want to use them in clean
        # or we can pass them in __init__ and store them
        
        if self.user:
            if self.user.is_superuser:
                is_admin = True
            elif self.tenant:
                role = get_user_role(self.user, self.tenant)
                if role in ["admin", "system_admin", "campaign_admin"]:
                    is_admin = True

        if not is_admin and self.instance.pk:
            restricted_fields = [
                "first_name", "last_name", "voter_id", "district", "precinct", 
                "registration_date", "address_street", "city", "state", "zip_code"
            ]
            for field in restricted_fields:
                if field in self.changed_data:
                    # Revert to original value
                    cleaned_data[field] = getattr(self.instance, field)
        
        return cleaned_data

class AdvancedVoterSearchForm(forms.Form):
    MONTH_CHOICES = [
        ('', 'Any Month'),
        (1, 'January'), (2, 'February'), (3, 'March'), (4, 'April'),
        (5, 'May'), (6, 'June'), (7, 'July'), (8, 'August'),
        (9, 'September'), (10, 'October'), (11, 'November'), (12, 'December')
    ]

    first_name = forms.CharField(required=False)
    last_name = forms.CharField(required=False)
    address = forms.CharField(required=False)
    voter_id = forms.CharField(required=False, label="Voter ID")
    birth_month = forms.ChoiceField(choices=MONTH_CHOICES, required=False, label="Birth Month")
    city = forms.CharField(required=False)
    zip_code = forms.CharField(required=False)
    neighborhood = forms.CharField(required=False)
    district = forms.CharField(required=False)
    precinct = forms.CharField(required=False)
    email = forms.EmailField(required=False)  # Added email field
    phone_type = forms.ChoiceField(
        choices=[('', 'Any')] + Voter.PHONE_TYPE_CHOICES,
        required=False
    )
    is_targeted = forms.BooleanField(required=False, label="Targeted Only")
    door_visit = forms.BooleanField(required=False, label="Visited Only")
    candidate_support = forms.ChoiceField(
        choices=[('', 'Any')] + Voter.CANDIDATE_SUPPORT_CHOICES,
        required=False
    )
    yard_sign = forms.ChoiceField(
        choices=[('', 'Any')] + Voter.YARD_SIGN_CHOICES,
        required=False
    )
    window_sticker = forms.ChoiceField(
        choices=[('', 'Any')] + Voter.WINDOW_STICKER_CHOICES,
        required=False
    )
    min_total_donation = forms.DecimalField(required=False, min_value=0, label="Min Total Donation")
    max_total_donation = forms.DecimalField(required=False, min_value=0, label="Max Total Donation")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            if isinstance(field.widget, forms.CheckboxInput):
                field.widget.attrs.update({'class': 'form-check-input'})
            else:
                field.widget.attrs.update({'class': 'form-control'})
        
        self.fields['birth_month'].widget.attrs.update({'class': 'form-select'})
        self.fields['candidate_support'].widget.attrs.update({'class': 'form-select'})
        self.fields['yard_sign'].widget.attrs.update({'class': 'form-select'})
        self.fields['window_sticker'].widget.attrs.update({'class': 'form-select'})
        self.fields['phone_type'].widget.attrs.update({'class': 'form-select'})

class InteractionForm(forms.ModelForm):
    class Meta:
        model = Interaction
        fields = ['type', 'volunteer', 'date', 'description', 'notes']
        widgets = {
            'date': forms.DateTimeInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
            'notes': forms.Textarea(attrs={'rows': 2}),
        }

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['type'].queryset = InteractionType.objects.filter(tenant=tenant, is_active=True)
            self.fields['volunteer'].queryset = Volunteer.objects.filter(tenant=tenant)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['type'].widget.attrs.update({'class': 'form-select'})
        self.fields['volunteer'].widget.attrs.update({'class': 'form-select'})
        if self.instance and self.instance.date:
            self.initial['date'] = self.instance.date.strftime('%Y-%m-%dT%H:%M')

class DonationForm(forms.ModelForm):
    class Meta:
        model = Donation
        fields = ['date', 'method', 'amount']
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'}),
        }

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['method'].queryset = DonationMethod.objects.filter(tenant=tenant, is_active=True)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['method'].widget.attrs.update({'class': 'form-select'})

class VoterLikelihoodForm(forms.ModelForm):
    class Meta:
        model = VoterLikelihood
        fields = ['election_type', 'likelihood']

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['election_type'].queryset = ElectionType.objects.filter(tenant=tenant, is_active=True)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['election_type'].widget.attrs.update({'class': 'form-select'})
        self.fields['likelihood'].widget.attrs.update({'class': 'form-select'})

class EventParticipationForm(forms.ModelForm):
    class Meta:
        model = EventParticipation
        fields = ['event', 'participation_status']

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['event'].queryset = Event.objects.filter(tenant=tenant)
            self.fields['participation_status'].queryset = ParticipationStatus.objects.filter(tenant=tenant, is_active=True)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['event'].widget.attrs.update({'class': 'form-select'})
        self.fields['participation_status'].widget.attrs.update({'class': 'form-select'})

class EventParticipantAddForm(forms.ModelForm):
    class Meta:
        model = EventParticipation
        fields = ['voter', 'participation_status']

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            voter_id = self.data.get('voter') or self.initial.get('voter')
            if voter_id:
                self.fields['voter'].queryset = Voter.objects.filter(tenant=tenant, id=voter_id)
            else:
                self.fields['voter'].queryset = Voter.objects.none()
            self.fields['participation_status'].queryset = ParticipationStatus.objects.filter(tenant=tenant, is_active=True)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['voter'].widget.attrs.update({'class': 'form-select'})
        self.fields['participation_status'].widget.attrs.update({'class': 'form-select'})

class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = ['name', 'date', 'start_time', 'end_time', 'event_type', 'default_volunteer_role', 'description', 'location_name', 'address', 'city', 'state', 'zip_code', 'latitude', 'longitude']
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'}),
            'start_time': forms.TimeInput(attrs={'type': 'time'}),
            'end_time': forms.TimeInput(attrs={'type': 'time'}),
            'description': forms.Textarea(attrs={'rows': 2}),
        }

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['event_type'].queryset = EventType.objects.filter(tenant=tenant, is_active=True)
            self.fields['default_volunteer_role'].queryset = VolunteerRole.objects.filter(tenant=tenant, is_active=True)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['event_type'].widget.attrs.update({'class': 'form-select'})
        self.fields['default_volunteer_role'].widget.attrs.update({'class': 'form-select'})

class VoterImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class EventImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class EventParticipationImportForm(forms.Form):
    file = forms.FileField(label="Select CSV/Excel file")

    def __init__(self, *args, event=None, **kwargs):
        super().__init__(*args, **kwargs)
        # No tenant field needed as event_id is passed directly
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class ParticipantMappingForm(forms.Form):
    def __init__(self, *args, headers, tenant, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['email_column'] = forms.ChoiceField(
            choices=[(header, header) for header in headers],
            label="Column for Email Address",
            required=True,
            widget=forms.Select(attrs={'class': 'form-select'})
        )
        
        name_choices = [('', '-- Select Name Column (Optional) --')] + [(header, header) for header in headers]
        self.fields['name_column'] = forms.ChoiceField(
            choices=name_choices,
            label="Column for Participant Name",
            required=False,
            widget=forms.Select(attrs={'class': 'form-select'})
        )

        phone_choices = [('', '-- Select Phone Column (Optional) --')] + [(header, header) for header in headers]
        self.fields['phone_column'] = forms.ChoiceField(
            choices=phone_choices,
            label="Column for Phone Number",
            required=False,
            widget=forms.Select(attrs={'class': 'form-select'})
        )

        participation_status_choices = [('', '-- Select Status Column (Optional) --')] + [(header, header) for header in headers]
        self.fields['participation_status_column'] = forms.ChoiceField(
            choices=participation_status_choices,
            label="Column for Participation Status",
            required=False,
            widget=forms.Select(attrs={'class': 'form-select'})
        )

        # Optional: Add a default participation status if no column is mapped
        self.fields['default_participation_status'] = forms.ModelChoiceField(
            queryset=ParticipationStatus.objects.filter(tenant=tenant, is_active=True),
            label="Default Participation Status (if no column mapped or column is empty)",
            required=False,
            empty_label="-- Select a Default Status --",
            widget=forms.Select(attrs={'class': 'form-select'})
        )

class DonationImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class InteractionImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class VoterLikelihoodImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class VolunteerImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class VolunteerForm(forms.ModelForm):
    class Meta:
        model = Volunteer
        fields = ['first_name', 'last_name', 'email', 'phone', 'is_default_caller', 'notes', 'interests']
        widgets = {
            'notes': forms.Textarea(attrs={'rows': 3}),
            'interests': Select2MultipleWidget(),
        }

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            from .models import Interest
            self.fields['interests'].queryset = Interest.objects.filter(tenant=tenant)
        for field in self.fields.values():
            if not isinstance(field.widget, forms.CheckboxInput):
                field.widget.attrs.update({'class': 'form-control'})
            else:
                field.widget.attrs.update({'class': 'form-check-input'})

class VolunteerEventForm(forms.ModelForm):
    class Meta:
        model = VolunteerEvent
        fields = ['event', 'role_type']

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['event'].queryset = Event.objects.filter(tenant=tenant)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['event'].widget.attrs.update({'class': 'form-select'})

class VolunteerEventAddForm(forms.ModelForm):
    class Meta:
        model = VolunteerEvent
        fields = ['volunteer', 'role_type']

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            volunteer_id = self.data.get('volunteer') or self.initial.get('volunteer')
            if volunteer_id:
                self.fields['volunteer'].queryset = Volunteer.objects.filter(tenant=tenant, id=volunteer_id)
            else:
                self.fields['volunteer'].queryset = Volunteer.objects.none()
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['volunteer'].widget.attrs.update({'class': 'form-select'})

class VotingRecordImportForm(forms.Form):
    tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), label="Campaign")
    file = forms.FileField(label="Select CSV file")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['tenant'].widget.attrs.update({'class': 'form-control form-select'})
        self.fields['file'].widget.attrs.update({'class': 'form-control'})

class DoorVisitLogForm(forms.Form):
    OUTCOME_CHOICES = [
        ("No Answer Left Literature", "No Answer Left Literature"),
        ("Spoke to voter", "Spoke to voter"),
        ("No Access to House", "No Access to House"),
    ]
    outcome = forms.ChoiceField(
        choices=OUTCOME_CHOICES, 
        widget=forms.RadioSelect(attrs={"class": "btn-check"}),
        label="Outcome"
    )
    notes = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control", "rows": 3}),
        required=False,
        label="Notes"
    )
    wants_yard_sign = forms.BooleanField(
        required=False, 
        widget=forms.CheckboxInput(attrs={"class": "form-check-input"}),
        label="Wants a Yard Sign"
    )
    candidate_support = forms.ChoiceField(
        choices=Voter.CANDIDATE_SUPPORT_CHOICES,
        initial="unknown",
        widget=forms.Select(attrs={"class": "form-select"}),
        label="Candidate Support"
    )
    follow_up = forms.BooleanField(
        required=False,
        widget=forms.CheckboxInput(attrs={"class": "form-check-input"}),
        label="Follow Up"
    )
    follow_up_voter = forms.ChoiceField(choices=[], required=False, widget=forms.Select(attrs={"class": "form-select"}), label="Voter to Follow Up")

    def __init__(self, *args, voter_choices=None, **kwargs):
        super().__init__(*args, **kwargs)
        if voter_choices:
            self.fields["follow_up_voter"].choices = voter_choices
    call_notes = forms.CharField(
        widget=forms.Textarea(attrs={"class": "form-control", "rows": 2}),
        required=False,
        label="Call Notes"
    )

class ScheduledCallForm(forms.ModelForm):
    class Meta:
        model = ScheduledCall
        fields = ['volunteer', 'comments']
        widgets = {
            'comments': forms.Textarea(attrs={'rows': 3}),
        }

    def __init__(self, *args, tenant=None, **kwargs):
        super().__init__(*args, **kwargs)
        if tenant:
            self.fields['volunteer'].queryset = Volunteer.objects.filter(tenant=tenant)
            default_caller = Volunteer.objects.filter(tenant=tenant, is_default_caller=True).first()
            if default_caller:
                self.initial['volunteer'] = default_caller
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
        self.fields['volunteer'].widget.attrs.update({'class': 'form-select'})

class UserUpdateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs.update({'class': 'form-control'})
