# coding=utf8

from __future__ import unicode_literals, absolute_import, print_function

import traceback

import datetime
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User

from .types import ALERT_RATING_TYPE, LOGIN_AUTH_TYPE
from .area import City
from .tag import Tag
from .college import College

# Enumeration is deprecated, reference: http://git.gengmei.cc/backend/gm-types
from gm_types.gaia import (
    MEMBERSHIP_LEVEL,
    USER_RIGHTS_LEVEL,
    BLOOD_TYPE,
)
from rpc.tool.random_tool import random_str
from rpc.tool.dict_mixin import to_dict

from gm_upload import IMG_TYPE, ImgUrlField
from api.tool.image_utils import get_thumb_path
from mimas.event_manager import EventDispatcher


class UserExtra(models.Model):
    """
    以下字段定义已复制到passport项目, 如需修改请联系passport负责人:
    user
    portrait
    """

    class Meta:
        verbose_name = '用户附加信息'
        verbose_name_plural = '用户附加信息'
        db_table = 'api_userextra'
        app_label = 'api'

    user = models.OneToOneField(User, related_name="userextra")
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name=u'更新时间', auto_now=True, db_index=True)
    referral_code = models.CharField(max_length=10, null=False, default='', unique=True,
                                     verbose_name='邀请码')
    phone = models.CharField(max_length=20, verbose_name="手机号", null=True, blank=True, default='', db_index=True)
    phone_last_modified = models.DateTimeField(null=True, blank=True, verbose_name='手机号最后修改时间')
    address = models.CharField(max_length=100, verbose_name="个人地址", null=True, blank=True, default='')
    name = models.CharField(max_length=20, null=True, verbose_name='真实姓名', blank=True, default='')
    rating_click = models.CharField(max_length=1, null=True, blank=True, default=ALERT_RATING_TYPE.NEW_USER,
                                    verbose_name='好评提示点击')
    last_alert_rating_time = models.DateTimeField(auto_now_add=True, verbose_name='上次提示时间')
    points_amount = models.IntegerField(verbose_name='用户积分', default=0)
    alert_service = models.BooleanField(default=False)
    portrait = ImgUrlField(img_type=IMG_TYPE.USEREXTRA, verbose_name='头像', max_length=100, null=True, blank=True,
                           default='')
    cover = models.CharField(verbose_name='封面', max_length=100, null=True, blank=True, default=None)  # decprecated
    city = models.ForeignKey(City, verbose_name='城市', null=True)
    channel = models.CharField(verbose_name='注册渠道', max_length=64, default='null')
    auth_type = models.CharField(max_length=3, null=True, blank=True, default=None, choices=LOGIN_AUTH_TYPE,
                                 verbose_name='用户登陆类型')
    last_login = models.DateTimeField(default=None, verbose_name='最后登录时间', null=True)
    # update_time = models.DateTimeField(verbose_name=u'最后修改时间', auto_now=True, blank=True, null=True)
    show_recommend_follow_tags = models.BooleanField(default=True, verbose_name='是否显示圈子推荐页')
    membership_level = models.CharField(
        max_length=1, choices=MEMBERSHIP_LEVEL, default=MEMBERSHIP_LEVEL.NORMAL,
        verbose_name='用户级别，普通|达人'
    )
    zip_code = models.CharField(max_length=6, default='', verbose_name='邮政编码')
    login_mars = models.BooleanField(u'是否能登录mars系统', default=False)
    user_rights_level = models.CharField(max_length=2, choices=USER_RIGHTS_LEVEL, default=USER_RIGHTS_LEVEL.V1,
                                         verbose_name='用户权益等级')
    birthday = models.DateField(blank=True, null=True, verbose_name=u'生日')
    blood_type = models.CharField(max_length=12, null=True, blank=True, default=None, choices=BLOOD_TYPE, verbose_name=u"血型")
    current_city_id = models.CharField(max_length=40, verbose_name=u'用户最近当前城市', default=None, blank=True)
    risk_result = models.CharField(verbose_name=u'风险评估结果', default='0', max_length=32)
    risk_score = models.IntegerField(verbose_name=u'风险评估系数', default=10, max_length=3)
    risk_check = models.BooleanField(verbose_name=u'是否风险检测', default=False)
    is_good_looking = models.BooleanField(verbose_name=u'是否高颜值用户', default=False)

    @classmethod
    def create_user(cls, username, email, password, login_auth_type=LOGIN_AUTH_TYPE.phone, portrait=''):
        from api.tool.user_tool import get_user_extra_by_user_id
        from api.util.user_util import create_platform_user

        user = User.objects.create_user(username, "", random_str(16))
        user.last_name = '更美用户%s' % random_str(10)
        user.save()

        user_extra = get_user_extra_by_user_id(user.id)
        user_extra.portrait = portrait
        user_extra.auth_type = login_auth_type
        if login_auth_type == LOGIN_AUTH_TYPE.phone and len(username) == 11:
            user_extra.phone = username
        user_extra.save()
        create_platform_user(login_auth_type, username, user.id)
        # push signal to mimas
        if login_auth_type == LOGIN_AUTH_TYPE.phone:
            EventDispatcher.sent_bind_phone_signal(user_extra.user_id)

        return user

    def get_portrait(self):
        if self.portrait:
            return get_thumb_path(self.portrait)
        else:
            return get_thumb_path(settings.DEFAULT_PORTRAIT)

    def to_dict(self):
        result = to_dict(self)
        return result

    @classmethod
    def get_membership_level(cls, user):
        if not hasattr(user, 'userextra'):
            return MEMBERSHIP_LEVEL.NORMAL

        return user.userextra.membership_level

    @property
    def constellation(self):
        if not self.birthday or int(self.user_rights_level) < int(USER_RIGHTS_LEVEL.V4):
            return ''

        return _get_constellation(self.birthday.month, self.birthday.day)

    @property
    def constellation_icon(self):
        if self.is_doctor:
            return ''

        return settings.CONSTELLATION_IMG.get(self.constellation, '')

    @property
    def level_icon(self):
        if self.is_doctor:
            return ''

        return settings.LEVEL_IMG[self.user_rights_level]

    @property
    def membership_icon(self):
        if self.is_doctor:
            return ''

        return settings.MEMBERSHIP_IMG[self.membership_level]

    @property
    def user_level_icon(self):
        if self.is_doctor:
            return {
                'membership_icon': '',
                'level_icon': '',
                'constellation_icon': '',
            }

        return {
            'membership_icon': self.membership_icon if self.membership_icon else '',
            'level_icon': self.level_icon if self.level_icon else '',
            'constellation_icon': self.constellation_icon if self.constellation_icon else '',
        }

    @property
    def birthday_str(self):
        return self.birthday.strftime('%Y-%m-%d') if self.birthday else ''

    @property
    def is_doctor(self):
        if hasattr(self.user, 'doctor'):
            doc_obj = self.user.doctor
            if doc_obj.is_online:
                return True

        return False

    @property
    def related_doctor_id(self):
        if hasattr(self.user, 'doctor'):
            doc_obj = self.user.doctor
            if doc_obj.is_online:
                return doc_obj.id
        return None

    @property
    def related_doctor_type(self):
        if hasattr(self.user, 'doctor'):
            doc_obj = self.user.doctor
            if doc_obj.is_online:
                return doc_obj.doctor_type
        return None

    @property
    def age(self):
        if self.birthday:
            return datetime.date.today().year - self.birthday.year
        else:
            return None

    def get_city(self):
        if not self.city:
            return {}
        return {
            "id": self.city.id,
            "name": self.city.name
        }


def _get_constellation(month, date):
    dates = (21, 20, 21, 21, 22, 22, 23, 24, 24, 24, 23, 22)
    constellations = ("Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra",
                      "Scorpio", "Sagittarius", "Capricorn")
    if date < dates[month - 1]:
        return constellations[month - 1]
    else:
        return constellations[month]


class UserTag(models.Model):
    class Meta:
        verbose_name = u"用户标签"
        verbose_name_plural = u"用户标签"
        app_label = 'api'

    user = models.ForeignKey(User)
    tag = models.ForeignKey(Tag)

    def __unicode__(self):
        return "%s:%s" % (self.user.username, self.tag.name)


class MarkUser(models.Model):
    class Meta:
        verbose_name = u'给用户备注信息'
        verbose_name_plural = u'给用户备注信息'
        app_label = 'api'

    user = models.ForeignKey(User, verbose_name=u'操作备注的用户', related_name='mark_users')
    target_user = models.ForeignKey(User, verbose_name=u'被备注的用户')
    comment = models.CharField(verbose_name='备注内容', max_length=100, blank=True, null=True)
    last_modified = models.DateTimeField(auto_now=True, verbose_name=u"最后修改时间")


class UserInnerInfo(models.Model):
    class Meta:
        verbose_name = u'用户内部信息'
        verbose_name_plural = u'内部用户额外信息（运营／商务）'
        app_label = 'api'

    phone = models.CharField(max_length=20, verbose_name=u'手机号', null=True, blank=True, default='')
    name = models.CharField(max_length=30, verbose_name=u'真实姓名', null=True, blank=True, default='')
    wx_email = models.CharField(max_length=45, verbose_name=u'微信邮箱', null=True, blank=True, default='')
    user = models.OneToOneField(User, related_name="userinnerinfo")


class UserAuthentication(models.Model):
    class Meta:
        verbose_name = u'用户实名制手机号信息'
        verbose_name_plural = u'用户实名制手机号信息'
        app_label = 'api'

    phone = models.CharField(max_length=20, verbose_name=u'手机号')
    user_id = models.IntegerField(verbose_name=u'用户id', db_index=True)


class UserExtraToCollege(models.Model):
    class Meta:
        verbose_name = '用户大学关系表'
        app_label = 'api'
        unique_together = ('college', 'userextra')

    college = models.ForeignKey(College, verbose_name=u'兴趣大学', null=True)
    userextra = models.ForeignKey(UserExtra, verbose_name=u'用户', null=True)


class UserExtraWechatInfo(models.Model):
    class Meta:
        verbose_name = '微信登陆后用户基础信息'
        app_label = 'api'

    user = models.OneToOneField(User, verbose_name=u'用户')
    openid = models.CharField(verbose_name=u'小程序openid', max_length=128)
    wechat_nickname = models.CharField(verbose_name=u'用户昵称', max_length=128)


class PlatformUser(models.Model):
    class Meta:
        verbose_name = '第三方用户平台表'
        app_label = 'api'
        unique_together = ('platform_id', 'platform_type')

    user = models.ForeignKey(User)
    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
    update_time = models.DateTimeField(verbose_name=u'更新时间', auto_now=True, db_index=True)
    is_deleted = models.BooleanField(verbose_name=u'是否删除', default=False)
    is_bind = models.BooleanField(verbose_name='是否绑定(这里是是否有效的概念)', default=True)
    platform_type = models.SmallIntegerField(verbose_name='平台类型', choices=LOGIN_AUTH_TYPE,
                                             default=LOGIN_AUTH_TYPE.backend)
    platform_id = models.CharField(max_length=180, verbose_name='平台唯一id', null=False)
    extra_info = models.TextField(verbose_name='第三方平台的全部数据, json')

    @classmethod
    def get_platform_record_by_user_id(cls, user_id, platform_type):
        return PlatformUser.objects.filter(platform_type=platform_type, user=user_id, is_bind=1).all()

    @classmethod
    def get_user_by_type_id(cls, platform_type, platform_id):
        try:
            plu_obj = PlatformUser.objects.get(platform_type=platform_type, platform_id=platform_id)
            return plu_obj.user
        except PlatformUser.DoesNotExist:
            pass
        except:
            print(traceback.format_exc())
        return None


# class AttemptPlatformUser(models.Model):
#    class Meta:
#        verbose_name = '企图第三方登录的用户信息表'
#
#    create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
#    update_time = models.DateTimeField(verbose_name=u'更新时间', auto_now=True, db_index=True)
#    is_deleted = models.BooleanField(verbose_name=u'是否删除', default=False)
#    platform_type = models.SmallIntegerField(verbose_name='平台类型', choices=LOGIN_AUTH_TYPE, default=LOGIN_AUTH_TYPE.backend)
#    platform_id = models.CharField(max_length=180, verbose_name='平台唯一id', null=False)
#    device_id = models.CharField(max_length=100, verbose_name='设备id', null=False)

class UserNewOld(models.Model):
    """
    新旧用户
    """

    class Meta:
        verbose_name = u'消息推送2'
        verbose_name_plural = u'消息推送2'
        db_table = 'api_usernewold'
        app_label = 'api'

    user = models.OneToOneField(User, verbose_name=u'用户id', null=False, related_name='user_newold')
    is_new = models.BooleanField(verbose_name=u'是否是新用户，true是新，old是老', default=True)


class IOSUserDeviceMap(models.Model):
    """
    苹果用户的设备号关联
    """
    class Meta:
        db_table = 'api_ios_device'
        app_label = 'api'

    ios_user_id = models.CharField(verbose_name=u'苹果用户id', null=False, max_length=128)
    device_id = models.CharField(verbose_name=u'设备号', default='', max_length=128)
    create_time = models.DateTimeField(u'创建时间', auto_now_add=True)
