from django.conf import settings
from django.contrib.auth import models as auth_models
from django.contrib.auth.models import (UserManager, Group,
    BaseUserManager, Permission, AbstractBaseUser, PermissionsMixin)
from django.contrib.contenttypes.models import ContentType
from django.core import validators
from django.core.mail import send_mail
from django.db import models
from django.db.models.signals import post_migrate
from django.db.models.signals import post_save
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from sorl.thumbnail import ImageField

from ldt.user import MAX_USERNAME_LENGTH, MAX_FIRST_NAME_LENGTH, MAX_LAST_NAME_LENGTH

class LdtUserManager(BaseUserManager):

    def create_user(self, username, email=None, password=None, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        now = timezone.now()
        if not username:
            raise ValueError('The given username must be set')
        email = UserManager.normalize_email(email)
        user = self.model(username=username, email=email,
                          is_staff=False, is_active=True, is_superuser=False,
                          last_login=now, date_joined=now, **extra_fields)

        user.set_password(password)
        user.save(using=self._db)
        everyone, _ = Group.objects.get_or_create(name=settings.PUBLIC_GROUP_NAME)
        user.groups.add(everyone)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, password, **extra_fields):
        u = self.create_user(username, email, password, **extra_fields)
        u.is_staff = True
        u.is_active = True
        u.is_superuser = True
        u.save(using=self._db)
        return u

# This method was added to stabilize migrations
def get_group_image_upload_to(instance, filename):
    return settings.MEDIA_ROOT+"thumbnails/groups/"

def get_group_image_default():
    return settings.DEFAULT_GROUP_ICON

class GroupProfile(models.Model):
    group = models.OneToOneField(Group, primary_key=False, related_name='profile')
    description = models.TextField()
    image = ImageField(upload_to=get_group_image_upload_to, default=get_group_image_default, max_length=200)
    
    @staticmethod
    def create_group_profile(sender, instance, created, **kwargs):
        if created:
            profile = GroupProfile()
            profile.group_id = instance.id
            profile.save()
            admins = LdtUser.objects.filter(is_superuser=True)
            if admins:
                admin_user = admins[0] 
                admin_user.groups.add(instance)
                admin_user.save()

def get_ldtuser_image_default():
    return settings.DEFAULT_USER_ICON

def get_ldtuser_language_default():
    if hasattr(settings, 'LANGUAGE_CODE'):
        return settings.LANGUAGE_CODE[:2]
    else :
        return 'en'


class LdtUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.
    Username and password are required. Other fields are optional.
    """
    username = models.CharField(
        _('username'),
        max_length=MAX_USERNAME_LENGTH,
        unique=True,
        help_text=_('Required. %d characters or fewer. Letters, digits and @/./+/-/_ only.' % MAX_USERNAME_LENGTH),
        validators=[
            validators.RegexValidator(
                r'^[\w.@+-]+$',
                _('Enter a valid username. This value may contain only '
                  'letters, numbers ' 'and @/./+/-/_ characters.')
            ),
        ],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=MAX_FIRST_NAME_LENGTH, blank=True)
    last_name = models.CharField(_('last name'), max_length=MAX_LAST_NAME_LENGTH, blank=True)
    external_id = models.CharField(_('external id'), max_length=MAX_USERNAME_LENGTH, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
     
    language = models.CharField(max_length=2, default=get_ldtuser_language_default)
    image = ImageField(upload_to="thumbnails/users/", default=get_ldtuser_image_default, max_length=200)
     
    objects = LdtUserManager()
 
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']
 
    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
 
    def get_full_name(self):
        """
        Returns the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()
 
    def get_short_name(self):
        "Returns the short name for the user."
        return self.first_name
 
    def email_user(self, subject, message, from_email=None, **kwargs):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email], **kwargs)
     

def get_profile(self):
    return self.profile

Group.add_to_class("get_profile", get_profile)  # @UndefinedVariable
post_save.connect(GroupProfile.create_group_profile, sender=Group)


def add_group_permissions(sender, **kwargs):
    ct = ContentType.objects.get(app_label='auth', model='group')
    Permission.objects.get_or_create(codename='is_owner_group', name='Can add/delete admins to the group',content_type=ct)

post_migrate.connect(add_group_permissions, sender=auth_models)

