import os

from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm,\
    AuthenticationForm
from django.contrib.auth.models import Group
from django.core.validators import MaxLengthValidator
from django.utils.translation import gettext as _
from ldt.user import MAX_USERNAME_LENGTH, MAX_FIRST_NAME_LENGTH,\
    MAX_LAST_NAME_LENGTH


User = get_user_model()

def update_field_length(field, length, help_text=None):
    field.widget.attrs['maxlength'] = length
    field.max_length = length
    if help_text:
        field.help_text = help_text

    # we need to find the MaxLengthValidator and change its
    # limit_value otherwise the auth forms will fail validation
    for v in field.validators:
        if isinstance(v, MaxLengthValidator):
            v.limit_value = length

    
class ProfileForm(UserChangeForm):
    
    def __init__(self, user=None, *args, **kwargs):
        #self.user = user
        super(ProfileForm, self).__init__(*args, **kwargs)
        
 
    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'password')

class AdminUserCreationForm(UserCreationForm):

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

    def __init__(self, *args, **kwargs):
        super(UserCreationForm, self).__init__(*args, **kwargs)
        update_field_length(
            self.fields['username'],
            MAX_USERNAME_LENGTH,
            _("Required, %(username_length)s characters or fewer. Only letters, "
              "numbers, and @, ., +, -, or _ "
              "characters.") % {'username_length' : MAX_USERNAME_LENGTH})
        if 'first_name' in self.fields:
            update_field_length(self.fields['first_name'], MAX_FIRST_NAME_LENGTH, None)
        if 'last_name' in self.fields:
            update_field_length(self.fields['last_name'], MAX_LAST_NAME_LENGTH, None)

    def clean_username(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        username = self.cleaned_data["username"]
        try:
            User.objects.get(username=username)
        except User.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])
    
    def save(self, commit=True):
        user = super(AdminUserCreationForm, self).save(commit=False)
        
        public_group_name = getattr(settings,'PUBLIC_GROUP_NAME', None)
        
        if public_group_name:
            def save_m2m():
                if public_group_name not in [g.name for g in user.groups.all()]:
                    everyone, _ = Group.objects.get_or_create(name=public_group_name)
                    user.groups.add(everyone)
            if commit:
                user.save()
                save_m2m()
                user.save()
            else:
                old_save_m2m = getattr(self, 'save_m2m', lambda: None)
                self.save_m2m = lambda: [old_save_m2m(), save_m2m()]
        
        return user



class AdminUserChangeForm(UserChangeForm):
    language = forms.ChoiceField(label=_("Language"), choices=[(k,_(v)) for k,v in settings.LANGUAGES], initial=settings.LANGUAGE_CODE[:2])
    image = forms.ImageField(label=_("Profile picture"), required=False)    

    def clean_image(self):
        image = self.cleaned_data['image']

        if not image:
            return settings.DEFAULT_USER_ICON

        if image and image.size > settings.PROFILE_IMG_MAX_SIZE:
            raise forms.ValidationError(_("Image size is limited to %s" % settings.PROFILE_IMG_MAX_SIZE))

        if image != self.instance.image:    
            filename = image.name
            ext = filename.split(".")[-1]
            image.name = os.path.join(os.path.dirname(filename),str(self.instance.id) + "." + ext)
        
        return image

        def __init__(self, *args, **kwargs):
            super(UserCreationForm, self).__init__(*args, **kwargs)
            update_field_length(
                self.fields['username'],
                MAX_USERNAME_LENGTH,
                _("Required, %(username_length)s characters or fewer. Only letters, "
                  "numbers, and @, ., +, -, or _ "
                  "characters.") % {'username_length' : MAX_USERNAME_LENGTH})
            update_field_length(self.fields['first_name'], MAX_FIRST_NAME_LENGTH, None)
            update_field_length(self.fields['last_name'], MAX_LAST_NAME_LENGTH, None)

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

class AdminAuthenticationForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super(AdminAuthenticationForm, self).__init__(*args, **kwargs)
        update_field_length(
            self.fields['username'],
            MAX_USERNAME_LENGTH,
            _("Required, %(username_length)s characters or fewer. Only letters, "
              "numbers, and @, ., +, -, or _ "
              "characters.") % {'username_length' : MAX_USERNAME_LENGTH})


class LanguageChangeForm(forms.Form):
    language = forms.ChoiceField(label=_("Language"), choices=settings.LANGUAGES)
    
    def __init__(self, user=None, *args, **kwargs):
        self.user = user
        super(LanguageChangeForm, self).__init__(*args, **kwargs)
        
    def save(self):
        self.user.language = self.cleaned_data['language']
        self.user.save()
        return self.user
           
class PictureForm(forms.Form):
    image=forms.ImageField(label=_("Profile picture"), required=False)
    url_image=forms.CharField(max_length=1024, required=False)
    
    def __init__(self, model=None, *args, **kwargs):
        self.model = model
        super(PictureForm, self).__init__(*args, **kwargs)
        
    def clean_image(self):
        image = self.cleaned_data['image']

        if image and image.size > settings.PROFILE_IMG_MAX_SIZE:
            raise forms.ValidationError(_("Image size is limited to %s" % settings.PROFILE_IMG_MAX_SIZE))
    
        return image
    
    def save(self):
        
        if not self.cleaned_data['image']:
            return None
        
        class_name = self.model.__class__.__name__
        if isinstance(self.model, Group):
            instance_name = "%s" % self.model.id
            img_container = self.model.get_profile()
        if isinstance(self.model, User):
            instance_name = "%s" % self.model.id
            img_container = self.model
        elif class_name == 'Content':
            instance_name = self.model.iri_id
            img_container = self.model
        elif class_name == 'Project':
            instance_name = self.model.ldt_id
            img_container = self.model
            
        # We change the file name and keep the extension.
        filename = self.cleaned_data['image'].name
        ext = filename.split(".")[-1]
        self.cleaned_data['image'].name = instance_name + "." + ext
        # We save the picture with the correct name
        img_container.image = self.cleaned_data['image']
        img_container.save()
        return self.model

        