# coding=utf8

from __future__ import unicode_literals, absolute_import, print_function

from django.db import models
from django.conf import settings
from django.utils.functional import cached_property
from gm_types.gaia import TOPIC_TYPE
from . import Problem

from . import TopicImage
from talos.services import UserService
from talos.services.tag import TagService
from utils.exceptions import  Impossible


class ColumnTab(models.Model):
    """
    更美专栏tab
    """
    class Meta:
        verbose_name = '专栏tab'
        verbose_name_plural = '专栏tab'
        db_table = 'api_columntab'
        app_label = 'talos'

    name = models.CharField(default='', max_length=10, null=True, blank=True, verbose_name=u'专栏tab名')
    is_online = models.BooleanField(default=True, verbose_name=u"是否有效")
    order = models.IntegerField(default=0, blank=True, verbose_name=u"tab序号", help_text=u"小的排在前,大的排在后")
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=u"tab创建时间")
    last_modified = models.DateTimeField(auto_now=True, verbose_name=u"最后修改时间", null=True)

    def __unicode__(self):
        return "<ColumnTab:%d:%s>" % (self.id, self.name)

    @cached_property
    def tags(self):
        ts = ColumnTabTag.objects.filter(column_tab=self).values_list('tag_id', flat=True)
        _tags = TagService.get_tags_by_tag_ids(list(ts))
        return _tags or []

    @classmethod
    def tabs(cls):
        ts = ColumnTab.objects.filter(is_online=True).order_by('order')
        return ts

    @classmethod
    def get_tab_by_id(cls, tab_id):
        try:
            return ColumnTab.objects.get(id=tab_id)
        except ColumnTab.DoesNotExist:
            return None

    @property
    def data(self):
        _format = '%Y-%m-%d %H:%M:%S'
        return {
            'id': self.id,
            'name': self.name,
            'order': self.order,
            'created_time': self.created_time.strftime(_format),
            'last_modified': self.last_modified.strftime(_format),
        }

    @property
    def articles(self):
        tab_tags = ColumnTabTag.objects.filter(column_tab=self.id).values_list('tag_id', flat=True)
        articles = Problem.objects.filter(
            is_online=True,
            topic_type__in=[TOPIC_TYPE.COLUMN_ARTICLE, TOPIC_TYPE.USER_ARTICLE],
            problemtag__tag_id__in=tab_tags
        ).distinct().order_by('-last_modified')
        return articles

    @property
    def articles_exists(self):
        tab_tags = ColumnTabTag.objects.filter(column_tab=self.id).values_list('tag_id', flat=True)
        est = Problem.objects.filter(
            is_online=True,
            topic_type__in=[TOPIC_TYPE.COLUMN_ARTICLE, TOPIC_TYPE.USER_ARTICLE],
            problemtag__tag_id__in=tab_tags
        ).exists()
        return est


class ColumnTabTag(models.Model):
    """
    专栏tab-关联-tag
    """
    class Meta:
        app_label = 'talos'
        db_table = 'api_columntabtag'

    column_tab = models.ForeignKey(ColumnTab)
    tag_id = models.IntegerField(verbose_name=u"关联的tag_id")

    def __unicode__(self):
        return "%s:%d" % (self.tag_id, self.column_tab.id)

    @classmethod
    def create_bind(cls, column_tab_id, tag_id):
        tab_exists = ColumnTab.objects.filter(id=column_tab_id).exists()
        tag_exists = TagService.get_tag_by_tag_id(id=tag_id) is not None
        if tab_exists and tag_exists:
            tt = cls()
            tt.column_tab_id = column_tab_id
            tt.tag_id = tag_id
            tt.save()
            return True
        else:
            return False


class Columnist(models.Model):
    """
    专栏作者
    """
    class Meta:
        verbose_name = '专栏作者'
        verbose_name_plural = '专栏作者'
        db_table = 'api_columnist'
        app_label = 'talos'

    user_id = models.IntegerField(default=0, null=True, db_index=True, unique=True, verbose_name=u"关联的User表id")
    introduction = models.CharField(default='', max_length=50, blank=True, null=True, verbose_name=u'专栏作者简介')
    profession = models.CharField(default='', max_length=20, blank=True, null=True, verbose_name=u'专栏作者职业')
    is_online = models.BooleanField(default=True, verbose_name=u"是否在线")

    def __unicode__(self):
        return "<Columnist:%d:%s>" % (self.id, self.user_id)


class ArticleCard(models.Model):
    """
    专栏文章关联卡片(美购,医生,医院)
    """
    class Meta:
        verbose_name = '专栏文章关联卡片'
        verbose_name_plural = '专栏文章关联卡片'
        db_table = 'api_columncard'
        app_label = 'talos'
        
    article = models.ForeignKey(Problem)
    service_id = models.IntegerField(default=None, null=True, db_index=True, verbose_name=u"关联的美购id")
    doctor_id = models.CharField(default=None, max_length=100, null=True, db_index=True, verbose_name=u"关联的医生id")
    hospital_id = models.CharField(default=None, max_length=100, null=True, db_index=True, verbose_name=u"关联的医院id")
    diary_id = models.IntegerField(default=None, null=True, verbose_name=u"关联的日记本id")
    answer_id = models.IntegerField(default=None, null=True, db_index=True, verbose_name=u'关联的回答')
    rankboard_id = models.IntegerField(default=None, null=True, db_index=True, verbose_name=u'关联榜单')


class Article(models.Model):
    """
    文章关联(目前支持专栏文章、优质用户文章)
    """
    class Meta:
        verbose_name = '文章关联'
        verbose_name_plural = '文章关联'
        db_table = 'api_article'
        app_label = 'talos'
    article_id = models.IntegerField(default=None, unique=True, null=True, verbose_name=u"一一对应的帖子中文章")
    article_type = models.CharField(max_length=10, null=False, verbose_name=u'文章类型',
                                    default=TOPIC_TYPE.USER_ARTICLE, choices=TOPIC_TYPE, db_index=True)
    is_online = models.BooleanField(default=True, help_text=u"是否可以上线", verbose_name=u"上线", db_index=True)
    created_time = models.DateTimeField(auto_now_add=True, verbose_name=u"创建时间")
    last_modified = models.DateTimeField(auto_now=True, verbose_name=u"最后修改时间", null=True)

    def __unicode__(self):
        return "<Article:%d:%s>" % (self.id, self.article_id)

    @property
    def data(self):
        image = TopicImage.objects.filter(topic=self.article_id, is_cover=True)
        topic = Problem.objects.filter(id=self.article_id, is_online=True)
        user_id = topic[0].user_id if topic else None
        columnist = Columnist.objects.filter(user_id=user_id, is_online=True) if user_id else None
        user = UserService.get_user_by_user_id(user_id=user_id) if user_id else None
        title = topic[0].title if topic else ""
        content = topic[0].ask if topic else ""

        return {
            'reply_num': topic[0].reply_num if topic else 0,
            'portrait': user.portrait if user else '',
            'article_id': self.article_id,
            'head_image': image[0].get_image_data() if image else None,  # 封面
            'area': user.city_name if user else None,  # 作者坐标
            'introduction': columnist[0].introduction if columnist else '',  # 作者简介
            'user_id': user.id if user else -1,
            'title': title,
            'is_voted': topic[0].is_voted(user_id) if topic else False,
            'vote_num': topic[0].vote_amount if topic else 0,
            'view_num': topic[0].view_amount if topic else 0,
            'content': content,
            'user_level': {
                'membership_icon': user.membership_icon if user else '',
                'level_icon': user.level_icon if user else '',
                'constellation_icon': user.constellation_icon if user else ''
            },
            'nickname': user.nickname if user else '',  # 作者昵称
            'user_name': user.nickname if user else '',  # 作者昵称
            'images': [item.get_image_data() for item in image]
        }

    @classmethod
    def last_articles(cls, article_type_list, num):
        _max_num = 50
        if num > _max_num:
            num = _max_num
        last_articles = Article.objects.filter(article_type__in=article_type_list, is_online=True)[:num]
        return last_articles

    def _content_score(self, topic):
        if topic.is_push:
            return 100
        else:
            return 20

    def _reply_score(self, topic):
        reply_num = topic.reply_num
        if reply_num == 0:
            return 0
        elif 1 <= reply_num <= 30:
            return 50
        elif 31 <= reply_num:
            return 100
        else:
            raise Exception("impossible")

    def _like_score(self, topic):
        like_num = topic._get_vote_amount_of_id(topic.id)
        if like_num == 0:
            return 0
        elif 1 <= like_num <= 10:
            return 50
        elif 11 <= like_num:
            return 100
        else:
            raise Impossible

    def _time_score(self):
        created_date = self.created_time.date()
        delta = created_date - settings.FOUNDING_DAY
        return delta.days

    def topic(self):
        topics = Problem.objects.filter(id=self.article_id, is_online=True)
        return topics[0] if topics else None

    def smart_rank(self):
        topic = self.topic()
        if topic is None:
            return 0
        content_score = self._content_score(topic)
        social_score = settings.SOCIAL_REPLY_WEIGHT * self._reply_score(topic) + \
            settings.SOCIAL_LIKE_WEIGHT * self._like_score(topic)
        rank = settings.CONTENT_WEIGHT * content_score + \
            settings.SOCIAL_WEIGHT * social_score + \
            settings.TIME_WEIGHT * self._time_score()
        return rank






class ArticleAsk(models.Model):
    """
        文章关联(目前支持专栏文章、优质用户文章)
        """

    class Meta:
        verbose_name = '文章关联'
        verbose_name_plural = '文章关联'
        db_table = 'api_problem'
        app_label = 'talos'