# -*- coding: UTF-8 -*-

from django.db.models import Q, Count
from django.contrib.auth.models import User
from django.conf import settings

from gm_dataquery.db import DB
from gm_dataquery.dataquery import DataBuilder, DataSQLQuery
from gm_types.gaia import TOPIC_TYPE
from gm_types.gaia import USER_CLASSIFY

from rpc.exceptions import CODES, UniError
from rpc.tool.error_code import gen
from talos.models.topic import Problem as Topic, ActivityWinlist, ProblemTagV3
from talos.models.topic.column import Article
from talos.models.topic.column import ColumnTab, Columnist

from api.tool.image_utils import get_full_path
from message.views.message import api_internal_message_send
from hera.utils import shorten_text
from services.talos_service import topic_get_tags_by_id, topic_vote_amount_by_id
from talos.services.user import UserService
from statistic.models import ClassifyUser
from . import TalosDataSQLQuery


class TopicDB(DataBuilder):
    def getval_ask_wrap(self, obj):
        return shorten_text(obj.ask)

    def getval_answer_wrap(self, obj):
        return shorten_text(obj.answer)

    def getval_user__last_name(self, obj):
        return obj.user.nickname

    def getval_reply_num(self, obj):
        return obj.topicreply_set.count()

    def getval_vote_num(self, obj):
        vote_amount = topic_vote_amount_by_id(id=obj.id).get('vote_amount')
        return vote_amount

    def getval_images(self, obj):
        images = []
        for image in obj.images.all():
            images.append(get_full_path(image.image_url))
        return images

    def getval_activity_is_win(self, obj):
        if obj.activity:
            user = UserService.get_user_by_user_id(obj.user_id)
            win_list = ActivityWinlist.objects.filter(activity=obj.activity, person_id=user.person_id, topic=obj.id)
            if win_list:
                return True
        return False

    def getval_tags(self, obj):
        # tags = [tag['name'] for tag in obj.get_tags()]
        self_tags = topic_get_tags_by_id(id=obj.id)
        tags = [tag['name'] for tag in self_tags]
        return tags

    def getval_tags_id(self, obj):
        self_tags = topic_get_tags_by_id(id=obj.id)
        tags = [tag['tag_id'] for tag in self_tags]
        return tags

    def getval_last_reply(self, obj):
        # 性能问题使用id而不是reply_date 排序
        lastest_reply = obj.topicreply_set.order_by('-id').first()
        if lastest_reply:
            return lastest_reply.content
        else:
            return u'无'

    def getval_answer_richtext(self, obj, need_escape=False):
        return obj.answer_richtext

    def getval_is_star(self, obj):
        return obj.topic_type == TOPIC_TYPE.USER_ARTICLE

    def getval_tag_v3_ids(self, obj):
        return list(ProblemTagV3.objects.filter(problem_id=obj.id).values_list("tag_v3_id", flat=True))


@DB
class TopicDQ(TalosDataSQLQuery):
    model = Topic
    data_model = TopicDB

    def filter_is_real(self, srch_key, srch_val, regex=False):
        user_ids = ClassifyUser.objects.using(settings.SLAVE_DB_NAME).filter(
            classify=USER_CLASSIFY.MODEL).values_list('user_id', flat=True)
        q = Q(user_id__in=list(user_ids))
        if srch_val == u'1':
            return ~q
        else:
            return q

    def filter_created_time(self, srch_key, srch_val, regex=False):
        return self._qry_time_range(srch_key, srch_val, regex)

    def filter_is_win(self, srch_key, srch_val, regex=False):
        q = Q(id__in=ActivityWinlist.objects.values_list('topic', flat=True))
        return q if int(srch_val) else ~q

    def filter_tags(self, srch_key, srch_val, regex=False):
        if not srch_val:
            return None
        if isinstance(srch_val, (list, tuple)):
            q = Q(problemtag__tag_id__in=srch_val)
        else:
            q = Q(problemtag__tag_id=srch_val)
        return q

    def filter_tag_v3_ids(self, srch_key, srch_val, regex=False):
        topic_ids = list(ProblemTagV3.objects.filter(
            tag_v3_id=int(srch_val)
        ).values_list("problem_id", flat=True))
        return Q(pk__in=topic_ids)

    def order_reply_num(self, qs, field):
        qs = qs.annotate(num=Count(u'topicreply'))
        return qs, u'num'

    def update(self, updates, **kwargs):
        is_online = updates.get('is_online')
        if is_online is not None:
            Article.objects.filter(article_id=kwargs['id']).update(is_online=is_online)
        if updates.pop('win_free_activity', False):
            user_id = updates.pop('user_id')
            topic = Topic.objects.get(**kwargs)
            activity = topic.activity
            q = dict(activity=topic.activity, person_id=topic.user.person_id)
            if ActivityWinlist.objects.filter(**q).exists():
                raise UniError('该用户已经已经中奖,不能重复中奖')
            if activity.win_limit <= activity.winners.count():
                return gen(CODES.ACTIVITY_REACH_WIN_LIMIT)
            ActivityWinlist.objects.create(
                activity=topic.activity,
                person_id=topic.user.person_id,
                topic=topic.id
            )
            text = u'【恭喜您在“{}”中获得免费名额，' \
                   u'稍后会有所长的小伙伴与您电话联系哦！】'.format(activity.title)
            api_internal_message_send.func(
                sender_user_id=user_id,
                target_user_id=topic.user.id,
                content={'text': text}
            )
        return super(TopicDQ.sqlquery, self).update(updates, **kwargs)


class ColumnTabDB(DataBuilder):
    def getval_tags(self, obj):
        return list(obj.columntabtag_set.values_list('tag_id', flat=True))


@DB
class ColumnTabDQ(TalosDataSQLQuery):
    model = ColumnTab
    data_model = ColumnTabDB


class ColumnistDB(DataBuilder):
    def getval_user_name(self, obj):
        user = UserService.get_user_by_user_id(obj.user_id)
        return user.nickname


@DB
class ColumnistDQ(TalosDataSQLQuery):
    model = Columnist
    data_model = ColumnistDB

    def filter_user_name(self, srch_key, srch_val, regex=False):
        user_id = list(User.objects.filter(last_name__contains=srch_val).values_list('id', flat=True))
        return Q(user_id__in=user_id)
