from __future__ import annotations

from django import forms
from django.contrib.auth import get_user_model
from django.conf import settings
from django.core.exceptions import ValidationError
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field
from django.contrib.auth import get_user_model
from orgs.models import UserProfile


class MultiFileInput(forms.ClearableFileInput):
    allow_multiple_selected = True


class MultiFileField(forms.Field):
    widget = MultiFileInput

    def __init__(self, *args, **kwargs):
        kwargs.setdefault("required", False)
        super().__init__(*args, **kwargs)

    def to_python(self, data):
        # Accept a list of UploadedFile or an empty list/None
        return data

    def validate(self, value):
        # Only enforce presence if required=True
        if self.required and not value:
            raise forms.ValidationError("This field is required.")


class PickupRequestForm(forms.Form):

    name = forms.CharField(max_length=255)
    email = forms.EmailField(required=False)
    phone = forms.CharField(max_length=64, required=False)
    address = forms.CharField(widget=forms.Textarea)
    preferred_at = forms.DateTimeField(required=False, widget=forms.DateTimeInput(attrs={"type": "datetime-local"}))
    materials = forms.CharField(label="Materials/Notes", widget=forms.Textarea, required=False)
    photos = MultiFileField(widget=MultiFileInput, help_text="Optional: upload photos of scrap")


class ContactForm(forms.Form):
    name = forms.CharField(max_length=255)
    email = forms.EmailField()
    phone = forms.CharField(max_length=64, required=False)
    subject = forms.CharField(max_length=255, required=False)
    message = forms.CharField(widget=forms.Textarea)


class RegistrationForm(forms.Form):
    username = forms.CharField(max_length=150)
    email = forms.EmailField()
    password1 = forms.CharField(widget=forms.PasswordInput)
    password2 = forms.CharField(widget=forms.PasswordInput)
    role = forms.ChoiceField(choices=[(k, v) for k, v in UserProfile.ROLE_CHOICES if k != UserProfile.ROLE_OWNER])

    def clean_username(self):
        username = self.cleaned_data["username"].strip()
        User = get_user_model()
        if User.objects.filter(username__iexact=username).exists():
            raise forms.ValidationError("Username already taken.")
        return username

    def clean_email(self):
        email = self.cleaned_data["email"].strip()
        User = get_user_model()
        if User.objects.filter(email__iexact=email).exists():
            raise forms.ValidationError("Email already registered.")
        return email

    def clean(self):
        data = super().clean()
        p1 = data.get("password1")
        p2 = data.get("password2")
        if p1 and p2 and p1 != p2:
            self.add_error("password2", "Passwords do not match.")
        return data


class PublicUserForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ["first_name", "last_name", "email"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Field("first_name"),
            Field("last_name"),
            Field("email"),
        )


from api.models import Profile as ApiProfile
from orgs.models import UserProfile


class PublicProfileForm(forms.ModelForm):
    tags = forms.CharField(label="Tags", required=False, help_text="Comma-separated")

    class Meta:
        model = ApiProfile
        fields = ["bio", "interests", "industry"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Field("bio"),
            Field("interests"),
            Field("industry"),
            Field("tags"),
        )
        if self.instance and getattr(self.instance, "pk", None):
            try:
                names = list(self.instance.tags.names())
                self.fields["tags"].initial = ", ".join(names)
            except Exception:
                self.fields["tags"].initial = ""

    def save(self, commit: bool = True):
        profile = super().save(commit)
        tags = [t.strip() for t in self.cleaned_data.get("tags", "").split(",") if t.strip()]
        try:
            if commit and hasattr(profile, "tags"):
                profile.tags.set(tags)
        except Exception:
            pass
        return profile


class PublicUserPhotoForm(forms.ModelForm):
    remove_photo = forms.BooleanField(label="Remove current photo", required=False)

    class Meta:
        model = UserProfile
        fields = ["my_photo", "remove_photo"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["my_photo"].widget = forms.ClearableFileInput(attrs={
            "accept": "image/*",
            "class": "hidden",
            "id": "id_my_photo",
        })
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Field("my_photo"),
            Field("remove_photo"),
        )

    def clean_my_photo(self):
        f = self.cleaned_data.get("my_photo")
        if not f:
            return f
        try:
            content_type = getattr(f, "content_type", "")
            if content_type and not content_type.startswith("image/"):
                raise ValidationError("Please upload an image file.")
        except Exception:
            pass
        max_bytes = 5 * 1024 * 1024
        if getattr(f, "size", 0) and f.size > max_bytes:
            raise ValidationError("Image too large (max 5MB).")
        return f

    def save(self, commit: bool = True):
        instance: UserProfile = super().save(commit=False)
        remove = self.cleaned_data.get("remove_photo", False)
        new_file = self.cleaned_data.get("my_photo")
        if remove and not new_file:
            try:
                if instance.my_photo:
                    instance.my_photo.delete(save=False)
            except Exception:
                pass
            instance.my_photo = None
        if commit:
            instance.save()
        return instance


class PublicUserProfileExtraForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = [
            "phone",
            "job_title",
            "department",
            "preferred_language",
            "address_line1",
            "address_line2",
            "city",
            "state",
            "postal_code",
            "country",
        ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Render preferred_language as a dropdown of available LANGUAGES
        try:
            lang_choices = list(getattr(settings, "LANGUAGES", []))
        except Exception:
            lang_choices = []
        if lang_choices:
            self.fields["preferred_language"] = forms.ChoiceField(
                choices=[("", "—")] + lang_choices,
                required=False,
                label=self.fields.get("preferred_language").label if self.fields.get("preferred_language") else "Preferred language",
            )
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
            Field("phone"),
            Field("job_title"),
            Field("department"),
            Field("preferred_language"),
            Field("address_line1"),
            Field("address_line2"),
            Field("city"),
            Field("state"),
            Field("postal_code"),
            Field("country"),
        )
