from itertools import chain

from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.db import models
# from django.utils import six
# from django.utils.encoding import python_2_unicode_compatible
from six import python_2_unicode_compatible
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill
import six
from AnsjerPush.config import SERVER_DOMAIN


class PermissionsManager(models.Manager):
    use_in_migrations = True

    def get_by_natural_key(self, permName):
        return self.get(
            permName=permName
        )


class RoleManager(models.Manager):
    """
    The manager for the auth's Role model.
    """
    use_in_migrations = True

    def get_by_natural_key(self, roleName):
        return self.get(roleName=roleName)


class UserManager(BaseUserManager):

    def create_user(self, username, password, userID, is_active,
                    user_isValid, **extra_fields):
        user = self.model(
            username=username,
            userID=userID,
            is_active=is_active,
            user_isValid=user_isValid,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)

        role = Role.objects.get(rid=1)
        user.role.add(role)
        return user

    def create_superuser(self, username, password, userID, is_active,
                         user_isValid, **extra_fields):
        # extra_fields.setdefault('is_superuser', is_superuser)
        is_superuser = extra_fields.get('is_superuser', None)
        if is_superuser != 100 and is_superuser != 1:
            raise ValueError('Superuser must have is_superuser=1 or 100.')

        return self.create_user(username, password, userID, is_active,
                                user_isValid, **extra_fields)


@python_2_unicode_compatible
class Permissions(models.Model):
    permName = models.CharField(blank=True, null=True, max_length=32, unique=True, verbose_name=u'权限名称')
    description = models.CharField(blank=True, null=True, max_length=128, verbose_name=u'描述信息', default='')
    objects = PermissionsManager()

    def __str__(self):
        return "%s" % (
            six.text_type(self.description))

    class Meta:
        ordering = ['permName']
        db_table = 'permissions'
        verbose_name = u'role permission'
        verbose_name_plural = verbose_name
        unique_together = (('permName'),)
        app_label = "db1"
    def natural_key(self):
        return (self.permName)


class Role(models.Model):
    rid = models.SmallIntegerField(primary_key=True, unique=True, verbose_name=u'用户角色组ID')
    roleName = models.CharField(max_length=32, unique=True,
                                default='User', verbose_name=u'角色名称')
    permission = models.ManyToManyField(to='Permissions', blank=True, verbose_name=u'权限', db_table='role_permissions')
    Description = models.TextField(blank=True, default='', verbose_name=u'描述信息')

    objects = RoleManager()

    class Meta:
        ordering = ['roleName']
        db_table = 'role'
        verbose_name = u'用户角色'
        verbose_name_plural = verbose_name
        app_label = "db1"

    def __str__(self):
        return self.roleName

    def natural_key(self):
        return (self.roleName,)

    def get_all_permission(self):
        perms = self.permission.all()

        permslist = []
        if self.rid == 100:
            perms = Permissions.objects.all()
            for perm in perms:
                permslist.append(perm.permName)
            return permslist
        else:
            permlist_tmp = []
            for perm in perms:
                permlist_tmp.append(perm.permName)
            permSet = set(permlist_tmp)
            permslist = list(permSet)
            permslist.sort()
            return permslist


class Device_User(AbstractBaseUser):
    userID = models.CharField(blank=True, max_length=32, primary_key=True,
                              verbose_name=u'用户ID', unique=True)
    role = models.ManyToManyField(to='Role', blank=True, verbose_name=u'用户角色', db_table='user_role')

    username = models.CharField(max_length=64, verbose_name=u'用户名', default='', blank=True)
    password = models.CharField(max_length=128, verbose_name=u'密码')
    userEmail = models.EmailField(max_length=64, verbose_name=u'邮箱', default='', blank=True)
    # 实际的路径就是 MEDIA_ROOT/Image/filename,所以可用upload_to来指定文件存放的前缀路径
    userIconPath = ProcessedImageField(blank=True, upload_to='User/Images/', default='static/User/default.png',
                                       verbose_name=u'头像',
                                       # 图片将处理成85x85的尺寸
                                       processors=[ResizeToFill(85, 85)], )
    userIconUrl = models.URLField(blank=True, max_length=128, default=SERVER_DOMAIN
                                                                      + 'account/getAvatar/User/defaultUser.png')
    NickName = models.CharField(blank=True, max_length=64, default='', verbose_name=u'用户昵称')
    is_superuser = models.IntegerField(blank=True, default=0, verbose_name=u'用户类型')
    is_active = models.BooleanField(blank=True, default=False, verbose_name=u'用户活动状态')
    data_joined = models.DateTimeField(blank=True, verbose_name=u'加入时间', auto_now_add=True)
    last_login = models.DateTimeField(blank=True, verbose_name='u最后登录时间', auto_now=True)
    user_isValid = models.BooleanField(blank=True, default=False, verbose_name=u'用户有效性', help_text=u'是否是认证通过的用户')
    online = models.BooleanField(blank=True, default=False, verbose_name=u'用户登录状态')
    machine_code = models.CharField(blank=True, max_length=128, default='', verbose_name=u'机械码')

    language = models.CharField(blank=True, max_length=16, default='en', verbose_name=u'语言地区')
    # 手机注册增加字段
    phone = models.CharField(max_length=16, verbose_name=u'手机号', default='', blank=True)

    objects = UserManager()

    USERNAME_FIELD = 'userID'  # 必须有一个唯一标识
    REQUIRED_FIELDS = ['is_superuser']  # 创建superuser时的必须字段

    class Meta:
        ordering = ('-data_joined',)
        verbose_name = u'用户信息'
        db_table = 'device_user'
        get_latest_by = 'last_login'
        app_label = "db1"

    def __str__(self):
        return self.username

    def get_role_id(self):
        rids = []
        roles = self.role.all()
        for role in roles:
            rids.append(role.rid)
        return rids

    def get_all_permission(self):
        roles = self.role.all()
        perms = self.permission.all()

        permslist = []
        for role in roles:
            if role.rid == 100:
                perms = Permissions.objects.all()
                for perm in perms:
                    permslist.append(perm.permName)
                return permslist

        for perm in perms:
            permslist.append(perm.permName)

        permSet = set(permslist)
        for role in roles:
            permlist_tmp = []
            for perm in role.permission.all():
                permlist_tmp.append(perm.permName)

            permSet_tmp = set(permlist_tmp)
            permSet = permSet.union(permSet_tmp)
            permslist = list(permSet)
            permslist.sort()
            return permslist

    @property
    def is_staff(self):
        return self.is_superuser


class Device_Info(models.Model):
    id = models.CharField(blank=True, max_length=32, primary_key=True)
    userID = models.ForeignKey(Device_User, blank=True, to_field='userID', on_delete=models.CASCADE)
    NickName = models.CharField(blank=True, max_length=32, verbose_name=u'设备名称')
    UID = models.CharField(blank=True, max_length=32, verbose_name=u'设备UID', default='')
    SID = models.CharField(blank=True, max_length=32, verbose_name=u'服务器ID', default='')
    View_Account = models.CharField(blank=True, max_length=32, verbose_name=u'设备用户名称', default='')
    View_Password = models.CharField(blank=True, max_length=32, verbose_name=u'设备密码', default='')
    AudioFormat = models.IntegerField(blank=True, default=1, verbose_name=u'初始化影像')
    EventNotification = models.IntegerField(blank=True, verbose_name=u'报警类型', default=0)
    ChannelIndex = models.IntegerField(blank=True, verbose_name=u'通道号', default=0)
    Online = models.BooleanField(blank=True, default=False, verbose_name=u'设备是否在线')
    mMonitorIndex = models.IntegerField(blank=True, default=-1)
    Type = models.IntegerField(blank=True, verbose_name='设备类型')
    DebugMode = models.IntegerField(blank=True, verbose_name=u'调试模式', default=0)
    NotificationMode = models.IntegerField(blank=True, verbose_name=u'是否报警', default=0)
    qvgaLevel = models.BooleanField(blank=True, verbose_name=u'SD与HD画面', default=0,
                                    help_text=u'0代表：SD、1代表：HD')
    isShare = models.BooleanField(blank=True, verbose_name=u'共享设备',
                                  help_text=u'是否为共享获取的设备', default=False)
    primaryUserID = models.CharField(blank=True, verbose_name='主用户id', max_length=32, default='')
    primaryMaster = models.CharField(max_length=64, verbose_name=u'主用户名', default='')
    data_joined = models.DateTimeField(blank=True, verbose_name=u'设备添加时间', auto_now_add=True)
    update_time = models.DateTimeField(blank=True, verbose_name=u'更新时间', auto_now=True, null=True)

    ip = models.CharField(blank=True, max_length=20, default='', verbose_name=u'设备区域ip')
    area = models.CharField(blank=True, max_length=100, default='', verbose_name=u'设备区域area')
    # ios要求新增字段
    version = models.CharField(blank=True, max_length=20, default='', verbose_name=u'版本号')
    iSNotification = models.BooleanField(blank=True, verbose_name=u'报警通知 0:关闭,1:开启)', default=False)
    isVod = models.SmallIntegerField(blank=True, default=0, verbose_name='是否支持云存')  # 是否支持云存设备
    isExist = models.SmallIntegerField(blank=True, default=1, verbose_name='是否被删除')  # 是否被删除了(需主用户交互) 1存在，0不存在，2设备被重置
    ###
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.NickName

    def model_to_dict(self, fields=None, exclude=None):
        opts = self._meta
        data = {}
        for f in chain(opts.concrete_fields, opts.private_fields, opts.many_to_many):
            if not getattr(f, 'editable', False):
                continue
            if fields and f.name not in fields:
                continue
            if exclude and f.name in exclude:
                continue
            data[f.name] = f.value_from_object(self)
        return data

    class Meta:
        db_table = 'device_info'
        ordering = ('-data_joined',)
        verbose_name = u'用户设备信息表'
        verbose_name_plural = verbose_name
        app_label = "db1"


class Equipment_Info(models.Model):
    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
    devUid = models.CharField(default='', blank=True, max_length=32, verbose_name=u'设备ID')
    devNickName = models.CharField(blank=True, max_length=32, default='', verbose_name=u'设备昵称')
    Channel = models.IntegerField(default=1, blank=True, verbose_name=u'设备通道')
    eventType = models.IntegerField(default=0, blank=True, verbose_name=u'事件类型')
    status = models.BooleanField(blank=True, default=False, verbose_name=u'事件状态')
    alarm = models.CharField(blank=True, max_length=256, verbose_name=u'报警信息')
    eventTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'设备报警时间')
    receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
    userID_id =  models.CharField(default='', blank=True, max_length=32, verbose_name=u'用户ID')
    is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图，2,视频
    addTime = models.IntegerField(verbose_name='添加时间', default=0)

    def __str__(self):
        return self.id

    class Meta:
        db_table = 'equipment_info'
        verbose_name = u'设备信息推送表'
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        app_label = "db2"


# 系统发送信息新到用户
class SysMsgModel(models.Model):
    #更新
    id = models.AutoField(primary_key=True, verbose_name='自增id')
    userID_id =  models.CharField(default='', blank=True, max_length=32, verbose_name=u'用户ID')
    msg = models.TextField(blank=True, default='', verbose_name=u'消息发送内容')
    status = models.SmallIntegerField(verbose_name='是否已读', default=0)  # 0:否,1:是
    addTime = models.IntegerField(verbose_name='添加时间', default=0)
    updTime = models.IntegerField(verbose_name='更新时间', default=0)
    eventType = models.IntegerField(verbose_name='消息类型', default=0) # 默认系统消息类型,0系统消息，1 ipcamera消息
    uid = models.CharField(default='', max_length=20, db_index=True, verbose_name='设备UID')

    class Meta:
        db_table = 'sys_msg'
        verbose_name = '系统消息'
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        app_label = "db2"

# 设备推送重构
# 设备配置表，新
class UidSetModel(models.Model):
    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
    uid = models.CharField(max_length=20, db_index=True, unique=True, verbose_name='设备UID')
    channel = models.SmallIntegerField(default=0, verbose_name='通道数量')  #
    detect_status = models.SmallIntegerField(default=0, verbose_name='推送开关')  # 状态[0:关闭,1:开启,2:用户解绑]
    detect_interval = models.IntegerField(verbose_name='推送间隔', default=60)  # 秒
    addTime = models.IntegerField(verbose_name='添加时间', default=0)
    updTime = models.IntegerField(verbose_name='更新时间', default=0)
    ucode = models.CharField(max_length=32, verbose_name='设备产品码', default='')
    version = models.CharField(max_length=32, verbose_name='设备版本', default='')
    p2p_region = models.CharField(max_length=16, verbose_name='设备p2p区域', default='ALL')  # ALL CN EU US
    cloud_vod = models.SmallIntegerField(default=2, verbose_name='云存开关')  # 0,关闭，1开启，2,不支持
    tz = models.CharField(default='', max_length=16, verbose_name='设备时区')  # +8
    video_code = models.SmallIntegerField(default=0, verbose_name='编码类型')  # 0:264,1:265
    nickname = models.CharField(default='', max_length=64, verbose_name='设备昵称')
    ip = models.CharField(max_length=20, default='', verbose_name=u'设备ip')
    # 设备重置后第一次启动时间
    is_alexa = models.IntegerField(default=0, verbose_name='是否支持alexa')  # 0为不支持，1为支持，2为开启alexa发现
    detect_group = models.CharField(default='', max_length=32, verbose_name=u'检测类型')
    pwd = models.CharField(max_length=32, default='', verbose_name=u'设备密码')  # 暂时是预留字段
    resetTime = models.IntegerField(default=0, verbose_name='设备重置时间')
    region_alexa = models.CharField(max_length=8, verbose_name='设备alexa区域', default='ALL')  # ALL CN EU US
    deviceModel = models.CharField(blank=True, max_length=64, default='', verbose_name=u'设备型号')
    TimeZone = models.CharField(blank=True, max_length=50, default='', verbose_name=u'时区')
    TimeStatus = models.SmallIntegerField(default=0, verbose_name='同步手机时间开关。0：关闭，1：开启')
    SpaceUsable = models.CharField(blank=True, max_length=20, default='', verbose_name=u'可用空间')
    SpaceSum = models.CharField(blank=True, max_length=20, default='', verbose_name=u'总空间')
    MirrorType = models.IntegerField(blank=True, default=0, verbose_name=u'镜像类型 0:关闭镜像,1：上下镜像，2:左右镜像，3：上下左右镜像')
    RecordType = models.IntegerField(blank=True, default=0, verbose_name=u'录像模式(0:关闭,1:全是录像,3:报警录像)')
    OutdoorModel = models.IntegerField(blank=True, default=0, verbose_name=u'室外模式 0：关闭，1：开启')
    WIFIName = models.CharField(blank=True, max_length=50, default='', verbose_name=u'无线名称')
    isDetector = models.SmallIntegerField(default=0, verbose_name=u'侦测开关0:关闭,1:开启')
    DetectorRank = models.IntegerField(default=0, verbose_name=u'侦测灵敏度 0:低,1:中,2:高,3:最高')

    class Meta:
        db_table = 'uid_set'
        verbose_name = u'设备配置表'
        verbose_name_plural = verbose_name
        ordering = ('id',)
        app_label = "db1"


# 设备关联用户推送
class UidPushModel(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='自增id')
    userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
    uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
    appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
    app_type = models.IntegerField(default=0, verbose_name=u'app类型 1:ios,2:安卓')
    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0,apns 1,安卓gcm 2,极光
    token_val = models.CharField(default='', max_length=160, verbose_name=u'设备验证令牌')
    m_code = models.CharField(default='', max_length=64, verbose_name='手机唯一标识')
    addTime = models.IntegerField(verbose_name='添加时间', default=0)
    updTime = models.IntegerField(verbose_name='更新时间', default=0)
    lang = models.CharField(max_length=8, verbose_name='推送语言类型', default='en')  # en英文 cn中文
    tz = models.CharField(max_length=8, verbose_name='utc时区', default='0')

    class Meta:
        db_table = 'uid_push'
        verbose_name = '设备绑定'
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        app_label = "db1"


class UID_Preview(models.Model):
    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
    uid = models.CharField(default='', max_length=20, db_index=True, verbose_name='设备UID')
    channel = models.SmallIntegerField(verbose_name=u'通道号', default=0)
    addTime = models.IntegerField(verbose_name='添加时间', default=0)
    updTime = models.IntegerField(verbose_name='更新时间', default=0)

    class Meta:
        db_table = 'uid_preview'
        verbose_name = '设备预览图'
        verbose_name_plural = verbose_name
        ordering = ('id',)
        app_label = "db1"

class Access_Log(models.Model):
    id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
    user = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'用户')
    operation = models.CharField(max_length=100, db_index=True, default='', blank=True, verbose_name=u'操作')
    ip = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name=u'访问ip地址')
    url = models.CharField(max_length=150, default='', blank=True, verbose_name=u'访问路径')
    status = models.IntegerField(default=0, blank=True, verbose_name=u'状态')
    time = models.DateTimeField(null=True, blank=True, db_index=True, verbose_name=u'访问时间')
    content = models.TextField(blank=True, default='', verbose_name=u'参数内容')

    class Meta:
        db_table = 'access_log'
        verbose_name = u'访问日志表'
        verbose_name_plural = verbose_name
        app_label = "db1"

# 存储通表
class VodBucketModel(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='主键')
    bucket = models.CharField(max_length=30, verbose_name='设备UID')
    storeDay = models.IntegerField(default=0, verbose_name='存储生命周期(天)')
    content = models.TextField(verbose_name='描述', default='')
    endpoint = models.CharField(max_length=125, default='', verbose_name='存储节点')
    area = models.CharField(max_length=16, default='', verbose_name='区域')
    region = models.CharField(max_length=16, default='', verbose_name='regionID')

    addTime = models.IntegerField(verbose_name='添加时间', default=0)
    updTime = models.IntegerField(verbose_name='更新时间', default=0)

    mold = models.SmallIntegerField(default=0, verbose_name='存储区域类型')  # 0：国内阿里 1：国外aws

    def __str__(self):
        return self.id

    class Meta:
        db_table = 'vod_bucket'
        verbose_name = u'存储通信息'
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        app_label = "db1"


class VodHlsModel(models.Model):
    id = models.AutoField(primary_key=True, verbose_name='回放列表主键')
    uid = models.CharField(max_length=20, verbose_name='设备UID')
    channel = models.SmallIntegerField(default=0, verbose_name='通道')
    time = models.IntegerField(verbose_name='播放列表名字时间戳', default=0, db_index=True)
    endTime = models.IntegerField(verbose_name='删除时间', default=0)
    sec = models.IntegerField(verbose_name='秒数', default=0)
    bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, default=1,
                               verbose_name='存储空间')
    fg = models.SmallIntegerField(default=0,verbose_name='时间片段数') # 0为阿里云存储方案 >0为亚马逊方案


    def __str__(self):
        return self.id

    class Meta:
        db_table = 'vod_hls'
        verbose_name = u'云存回放信息表'
        verbose_name_plural = verbose_name
        ordering = ('-id',)
        app_label = "db1"

