from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.forms.models import construct_instance
from .models import Asset, Organization, UserProfile, Location, ItemType, Unit, Custodian


class OrganizationForm(forms.ModelForm):
    class Meta:
        model = Organization
        fields = ['name', 'description']
        labels = {
            'name': 'نام سازمان',
            'description': 'توضیحات',
        }
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3}),
        }


class LocationForm(forms.ModelForm):
    class Meta:
        model = Location
        fields = ['name', 'description']
        labels = {
            'name': 'نام مکان',
            'description': 'توضیحات',
        }
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3}),
        }


class ItemTypeForm(forms.ModelForm):
    class Meta:
        model = ItemType
        fields = ['name', 'description']
        labels = {
            'name': 'نام نوع دارایی',
            'description': 'توضیحات',
        }
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3}),
        }


class UnitForm(forms.ModelForm):
    class Meta:
        model = Unit
        fields = ['name']
        labels = {
            'name': 'نام واحد',
        }


class CustodianForm(forms.ModelForm):
    class Meta:
        model = Custodian
        fields = ['first_name', 'last_name', 'job_title', 'phone']
        labels = {
            'first_name': 'نام',
            'last_name': 'نام خانوادگی',
            'job_title': 'سمت',
            'phone': 'شماره تماس',
        }


class AssetForm(forms.ModelForm):
    custodian = forms.ModelChoiceField(
        queryset=Custodian.objects.none(),
        required=True,
        label='امین اموال',
    )

    class Meta:
        model = Asset
        fields = ['name', 'item_type', 'location', 'availability', 'custodian', 'unit', 'description']
        widgets = {
            'description': forms.Textarea(attrs={'rows': 4}),
        }
        labels = {
            'name': 'نام دارایی',
            'item_type': 'نوع دارایی',
            'location': 'مکان',
            'availability': 'وضعیت موجودی',
            'custodian': 'امین اموال',
            'unit': 'واحد',
            'description': 'توضیحات',
        }


class UserRegistrationForm(UserCreationForm):
    username = forms.CharField(
        max_length=150,
        label='نام کاربری',
        validators=[
            RegexValidator(
                regex=r'^[\w.@+\-\u200c ]+$',
                message='نام کاربری فقط می تواند شامل حروف، اعداد، فاصله، نقطه، @، +، - و _ باشد.'
            )
        ],
    )
    email = forms.EmailField(required=False, label='ایمیل')
    first_name = forms.CharField(max_length=30, required=True, label='نام')
    last_name = forms.CharField(max_length=30, required=True, label='نام خانوادگی')
    phone = forms.CharField(
        max_length=30,
        required=True,
        label='شماره تماس',
        validators=[
            RegexValidator(
                regex=r'^[0-9۰-۹+()\-\s]{7,20}$',
                message='شماره تماس معتبر نیست.'
            )
        ],
    )
    organization = forms.ModelChoiceField(queryset=Organization.objects.all(), label='سازمان')
    user_type = forms.ChoiceField(choices=UserProfile.USER_TYPES, label='نقش کاربر')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')
        labels = {
            'username': 'نام کاربری',
            'password1': 'رمز عبور',
            'password2': 'تایید رمز عبور',
        }

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

    def clean_phone(self):
        return self.cleaned_data['phone'].strip()

    def _post_clean(self):
        opts = self._meta
        exclude = self._get_validation_exclusions()
        exclude.add('username')
        self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
        try:
            self.instance.full_clean(exclude=exclude, validate_unique=False)
        except ValidationError as error:
            self._update_errors(error)
        if self._validate_unique:
            self.validate_unique()

    def save(self, commit=True):
        user = super().save(commit=False)
        user.email = self.cleaned_data.get('email') or ''
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        if commit:
            user.save()
            UserProfile.objects.create(
                user=user,
                organization=self.cleaned_data['organization'],
                user_type=self.cleaned_data['user_type'],
                phone=self.cleaned_data['phone'],
            )
        return user
