# coding=utf-8

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, Group
from django.utils import timezone
from rest_framework.utils import model_meta

from .consts import CONTENT_TYPE_SORTING, MENU_TO_MODEL
from apps.system.models import SysLog
from utils.exceptions import CustomError

class Department(models.Model):
    name = models.CharField(max_length=100, verbose_name=u"名称")
    notes = models.CharField(max_length=500, verbose_name=u"备注",blank=True,null=True)
    parent_id = models.IntegerField(verbose_name=u"父部门",null=True,blank=True)
    lft = models.IntegerField(verbose_name=u"左值")
    rgt = models.IntegerField(verbose_name=u"右值")

    def __str__(self):
        return self.name

    def __unicode__(self):
        return self.name

    @staticmethod
    def getById(id):
        try:
            id = int(id)
        except:
            raise CustomError(u'无效的部门ID')

        instance = Department.objects.filter(pk=id).first()
        if not instance:
            raise CustomError(u'未找到相应的部门')
        return instance

    def getCompany(self):
        instance = Department.objects.filter(parent_id__isnull=True, lft__lte=self.lft, rgt__gte=self.rgt).first()
        if not instance:
            raise CustomError(u'未找到部门所属的公司')
        return instance

    @staticmethod
    def getLft(instance):
        if instance:
            return instance.lft
        return 1

    class Meta:
        db_table = "staff_department"
        verbose_name = u"部门管理"
        ordering = ["parent_id", 'id']
        default_permissions = ()
        permissions = (
            ("view_department", u"浏览"),
            ("add_department", u"添加"),
            ("edit_department", u"修改"),
            ("delete_department", u"删除"),
        )

class UserManager(BaseUserManager):
    def create_administrator(self, username, password=None, **extra_fields):
        return self.create_user(User.ADMINSTRATOR, username, password, **extra_fields)

    def create_staff(self, username, password=None, **extra_fields):
        return self.create_user(User.STAFF, username, password, **extra_fields)

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

    def create_user(self, type, username, password=None, **extra_fields):
        if not username:
            raise CustomError(u'请输入用户名！')
        count = User.objects.filter(username=username).count()
        if count > 0:
            raise CustomError(u'该用户名已存在！')
        user = self.model(
            type=type,
            username=username,
            is_superuser=False,
            last_login=timezone.now(),
            **extra_fields
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def sort_perms(self, perms):
        def get_index(app_label, model):
            try:
                return CONTENT_TYPE_SORTING.index('{}-{}'.format(app_label, model))
            except:
                return 9999

        perms = perms.order_by('content_type__model', 'id')
        perms = sorted(perms, key=lambda n: get_index(n.content_type.app_label, n.content_type.model))
        return perms

    def get_menuname_of_contenttype(self, app_label, model):
        for menu in MENU_TO_MODEL:
            val = '{}-{}'.format(app_label, model)
            if val in menu[1]:
                return menu[0]
        return u'未分类'

    def save_group(self, id, name, permissions, user):
        name = name.strip(u' ')
        # old_permissions = None
        if id == None or id == '':
            is_exist = Group.objects.filter(name=name).first()
            if is_exist:
                raise CustomError(u'名称为[%s]的权限组已存在' % name)
            group = Group.objects.create(name=name)
            SysLog.objects.addnew(user, SysLog.INSERT, u"添加权限组[%s],id=%d" % (group.name, group.id))
        else:
            is_exist = Group.objects.filter(name=name).exclude(pk=id).first()
            if is_exist:
                raise CustomError(u'名称为[%s]的权限组已存在' % name)
            group = Group.objects.filter(pk=id).first()
            if not group:
                raise CustomError(u'未找到相应的权限组')
            group.name = name
            group.save()
            #    old_permissions = [p.id for p in group.permissions.all()]
            SysLog.objects.addnew(user, SysLog.UPDATE, u"修改权限组[%s],id=%d" % (group.name, group.id))
        group.permissions = permissions

class User(AbstractBaseUser, PermissionsMixin):
    ADMINSTRATOR = 1
    STAFF = 2

    type = models.PositiveSmallIntegerField(verbose_name=u"类型")
    department = models.ForeignKey(Department, verbose_name=u"所属部门", null=True, blank=True, on_delete=models.PROTECT)
    username = models.CharField(verbose_name=u'帐号', max_length=30, unique=True, db_index=True)
    is_active = models.BooleanField(verbose_name=u'激活', default=True)
    date_joined = models.DateTimeField(verbose_name=u'注册时间', default=timezone.now, editable=False)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []

    class Meta:
        db_table = "staff_user"
        verbose_name = u"账户管理"
        unique_together = [
            ('username')
        ]
        index_together = (
            'date_joined',
        )
        ordering = ['-id']
        default_permissions = ()
        permissions = (
            ("view_user", u"浏览"),
            ("add_user", u"添加"),
            ("edit_user", u"修改"),
            ("delete_user", u"删除"),
        )

    def __unicode__(self):
        return self.username

    def add_administrator(self):
        self.type = self.type | self.ADMINSTRATOR

    def add_staff(self):
        self.type = self.type | self.STAFF

    def is_staff(self):
        if self.type & self.STAFF:
            return True
        return False

    def is_administrator(self):
        if self.type & self.ADMINSTRATOR:
            return True
        return False

    def change_password(self, new_password, confirm_password, old_password):
        if new_password != confirm_password:
            raise CustomError(u'两次输入的密码不一致， 请检查')
        if not self.check_password(old_password):
            raise CustomError(u'原密码输入错误， 请检查')
        self.set_password(new_password)

    def update_item(self, validated_data):
        def update():
            info = model_meta.get_field_info(self)
            for attr, value in validated_data.items():
                if attr in info.relations and info.relations[attr].to_many:
                    field = getattr(self, attr)
                    field.set(value)
                else:
                    setattr(self, attr, value)

        if not 'username' in validated_data:
            raise CustomError(u'用户名不能为空！')
        count = User.objects.filter(username=validated_data['username']).exclude(id=self.id).count()
        if count > 0:
            raise CustomError(u'该用户名已存在！')

        if not 'password' in validated_data or not validated_data['password']:
            validated_data['password'] = self.password
            update()
        else:
            update()
            self.set_password(validated_data['password'])
        self.save()
        return self

