from __future__ import annotations

import logging

from django import forms
from django.contrib.auth import authenticate, get_user_model
from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, UserCreationForm
from django.utils import timezone

from .models import Business, BusinessMembership, Feedback, ProofCard, ReviewRequest

logger = logging.getLogger(__name__)
User = get_user_model()


class TrustForgeAuthenticationForm(AuthenticationForm):
    username = forms.CharField(
        label='Work email',
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'you@company.com',
                'autocomplete': 'email',
            }
        ),
    )
    password = forms.CharField(
        label='Password',
        strip=False,
        widget=forms.PasswordInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'Enter your password',
                'autocomplete': 'current-password',
            }
        ),
    )

    def clean(self):
        email = (self.cleaned_data.get('username') or '').strip().lower()
        password = self.cleaned_data.get('password')

        if email and password:
            matched_user = User._default_manager.filter(email__iexact=email).first()
            auth_username = matched_user.get_username() if matched_user else email
            self.user_cache = authenticate(self.request, username=auth_username, password=password)
            if self.user_cache is None:
                raise self.get_invalid_login_error()
            self.confirm_login_allowed(self.user_cache)

        return self.cleaned_data


class SignUpForm(UserCreationForm):
    first_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Avery'}),
    )
    last_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Stone'}),
    )
    email = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'owner@servicebrand.com',
                'autocomplete': 'email',
            }
        )
    )
    password1 = forms.CharField(
        label='Password',
        strip=False,
        widget=forms.PasswordInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'Create a password',
                'autocomplete': 'new-password',
            }
        ),
    )
    password2 = forms.CharField(
        label='Confirm password',
        strip=False,
        widget=forms.PasswordInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'Repeat your password',
                'autocomplete': 'new-password',
            }
        ),
    )

    class Meta(UserCreationForm.Meta):
        model = User
        fields = ('first_name', 'last_name', 'email', 'password1', 'password2')

    def clean_email(self):
        email = (self.cleaned_data.get('email') or '').strip().lower()
        if User._default_manager.filter(email__iexact=email).exists() or User._default_manager.filter(username__iexact=email).exists():
            raise forms.ValidationError('An account with this email already exists.')
        return email

    def save(self, commit=True):
        user = super().save(commit=False)
        email = self.cleaned_data['email']
        user.username = email
        user.email = email
        user.first_name = self.cleaned_data.get('first_name', '').strip()
        user.last_name = self.cleaned_data.get('last_name', '').strip()
        if commit:
            user.save()
        return user


class ProfileSettingsForm(forms.ModelForm):
    first_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Avery'}),
    )
    last_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Stone'}),
    )
    email = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'you@company.com',
                'autocomplete': 'email',
            }
        )
    )

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

    def clean_email(self):
        email = (self.cleaned_data.get('email') or '').strip().lower()
        email_exists = User._default_manager.filter(email__iexact=email).exclude(pk=self.instance.pk).exists()
        username_exists = User._default_manager.filter(username__iexact=email).exclude(pk=self.instance.pk).exists()
        if email_exists or username_exists:
            raise forms.ValidationError('Another account already uses this email.')
        return email

    def save(self, commit=True):
        user = super().save(commit=False)
        email = self.cleaned_data['email']
        user.email = email
        user.username = email
        user.first_name = self.cleaned_data.get('first_name', '').strip()
        user.last_name = self.cleaned_data.get('last_name', '').strip()
        if commit:
            user.save()
        return user


class TrustForgePasswordResetForm(PasswordResetForm):
    email = forms.EmailField(
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control form-control-lg',
                'placeholder': 'you@company.com',
                'autocomplete': 'email',
            }
        )
    )

    def send_mail(self, *args, **kwargs):
        try:
            return super().send_mail(*args, **kwargs)
        except Exception:
            logger.exception('Password reset email failed to send.')


class TrustForgeSetPasswordForm(SetPasswordForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['new_password1'].widget.attrs.update(
            {
                'class': 'form-control form-control-lg',
                'placeholder': 'Create a new password',
                'autocomplete': 'new-password',
            }
        )
        self.fields['new_password2'].widget.attrs.update(
            {
                'class': 'form-control form-control-lg',
                'placeholder': 'Confirm the new password',
                'autocomplete': 'new-password',
            }
        )


class BusinessOnboardingForm(forms.ModelForm):
    class Meta:
        model = Business
        fields = ('name', 'industry', 'primary_city', 'primary_state', 'google_review_url')
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control form-control-lg', 'placeholder': 'Summit Home Services'}),
            'industry': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'HVAC, Roofing, Plumbing, Junk Removal…'}),
            'primary_city': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Austin'}),
            'primary_state': forms.TextInput(attrs={'class': 'form-control text-uppercase', 'placeholder': 'TX'}),
            'google_review_url': forms.URLInput(attrs={'class': 'form-control', 'placeholder': 'https://g.page/r/.../review'}),
        }

    def clean_primary_state(self):
        return (self.cleaned_data.get('primary_state') or '').upper()


class BusinessSettingsForm(BusinessOnboardingForm):
    pass


class TeamMemberInviteForm(forms.Form):
    first_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Jamie'}),
    )
    last_name = forms.CharField(
        required=False,
        max_length=150,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Rivera'}),
    )
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'tech@servicebrand.com'})
    )
    role = forms.ChoiceField(
        choices=BusinessMembership.Role.choices,
        initial=BusinessMembership.Role.TECHNICIAN,
        widget=forms.Select(attrs={'class': 'form-select'}),
    )

    def clean_email(self):
        return (self.cleaned_data.get('email') or '').strip().lower()


class JobIntakeForm(forms.Form):
    business = forms.ModelChoiceField(
        queryset=Business.objects.filter(is_active=True),
        empty_label=None,
        widget=forms.Select(attrs={'class': 'form-select form-control-lg'}),
    )
    customer_name = forms.CharField(
        max_length=160,
        widget=forms.TextInput(attrs={'class': 'form-control form-control-lg', 'placeholder': 'Homeowner or business contact'}),
    )
    customer_email = forms.EmailField(
        required=False,
        widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'customer@example.com'}),
    )
    customer_phone = forms.CharField(
        required=False,
        max_length=40,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '(555) 555-0123'}),
    )
    service_type = forms.CharField(
        max_length=120,
        widget=forms.TextInput(attrs={'class': 'form-control form-control-lg', 'placeholder': 'Roof replacement, HVAC tune-up, junk removal…'}),
    )
    description = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3, 'placeholder': 'What did the crew complete on-site?'}),
    )
    customer_city = forms.CharField(
        max_length=120,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Austin'}),
    )
    customer_state = forms.CharField(
        max_length=2,
        widget=forms.TextInput(attrs={'class': 'form-control text-uppercase', 'placeholder': 'TX'}),
    )
    technician_name = forms.CharField(
        required=False,
        max_length=120,
        widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Luis R.'}),
    )
    completion_date = forms.DateField(
        initial=timezone.localdate,
        widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
    )
    project_value = forms.DecimalField(
        required=False,
        min_value=0,
        max_digits=10,
        decimal_places=2,
        widget=forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '4500'}),
    )
    before_photo = forms.FileField(
        required=False,
        widget=forms.ClearableFileInput(attrs={'class': 'form-control', 'accept': 'image/*'}),
    )
    after_photo = forms.FileField(
        required=False,
        widget=forms.ClearableFileInput(attrs={'class': 'form-control', 'accept': 'image/*'}),
    )
    anonymize_customer = forms.BooleanField(
        required=False,
        initial=True,
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}),
    )
    send_review_request = forms.BooleanField(
        required=False,
        initial=True,
        widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}),
    )
    review_channel = forms.ChoiceField(
        choices=ReviewRequest.Channel.choices,
        initial=ReviewRequest.Channel.EMAIL,
        widget=forms.Select(attrs={'class': 'form-select'}),
    )

    def __init__(self, *args, business: Business | None = None, **kwargs):
        super().__init__(*args, **kwargs)
        if business is not None:
            self.fields['business'].queryset = Business.objects.filter(pk=business.pk)
            self.fields['business'].initial = business
            self.fields['business'].widget = forms.HiddenInput()

    def clean_customer_state(self):
        return self.cleaned_data['customer_state'].upper()


class PublicFeedbackForm(forms.Form):
    experience = forms.ChoiceField(
        choices=Feedback.Experience.choices,
        widget=forms.RadioSelect,
    )
    testimonial = forms.CharField(
        required=False,
        widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'placeholder': 'Tell us what stood out about the service…'}),
    )

    def clean(self):
        cleaned_data = super().clean()
        experience = cleaned_data.get('experience')
        testimonial = (cleaned_data.get('testimonial') or '').strip()
        if experience in {Feedback.Experience.GREAT, Feedback.Experience.GOOD} and len(testimonial) < 12:
            self.add_error('testimonial', 'For positive feedback, add a short testimonial so it can power the proof card.')
        return cleaned_data


class ProofCardForm(forms.ModelForm):
    class Meta:
        model = ProofCard
        fields = [
            'customer_display_name',
            'is_anonymized',
            'testimonial_quote',
            'rating',
            'status',
            'is_featured',
            'attached_widget_label',
            'attached_pages',
        ]
        widgets = {
            'customer_display_name': forms.TextInput(attrs={'class': 'form-control'}),
            'is_anonymized': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'testimonial_quote': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
            'rating': forms.NumberInput(attrs={'class': 'form-control', 'min': 1, 'max': 5}),
            'status': forms.Select(attrs={'class': 'form-select'}),
            'is_featured': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'attached_widget_label': forms.TextInput(attrs={'class': 'form-control'}),
            'attached_pages': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
        }
