# coding=utf-8

from __future__ import absolute_import
import json
import random
from datetime import timedelta, datetime
from distutils.version import LooseVersion

from django.conf import settings
from django.db.models import Q, Count

from celery import shared_task
from gm_types.antispam import DocType
from gm_types.gaia import AUTHOR_TYPE, TAG_TYPE, DIARY_ORDER_TYPE, QUESTION_ORDER_TYPE
from gm_types.mimas import SPAM_LABEL, CONTENT_CLASS, SEND_ANSWER_STATUS, MEDIA_IMAGE_URL_SOURCE
from gm_types.mimas import APPLET_PAGE_FROM, APPLET_SUBSCRIBE_MSG_TYPE
from gm_types.push import PUSH_INFO_TYPE, AUTOMATED_PUSH
from gm_upload.utils.image_utils import Picture
from helios.rpc import RPCFaultException
from gm_protocol import GmProtocol

from talos.services.other import get_user_lastest_device_app_version_by_user_id
from utils.protocol import gm_protocol
from utils.rpc import rpc_client, logging_exception
from utils.push import push_task_to_user_multi, limit_get_comment_push, vote_push, send_applet_subscribe_msg
from qa.models import (
    Answer,
    AnswerVote,
    Question,
    AnswerReply,
    QuestionInviter,
    QuestionTag,
    SendAnswer,
    QuestionImage,
    AnswerImage,
    AnswerVoteReply,
    AnswerTag,
    AnswerReplyImages)
from talos.models.doctor import DoctorMessageList
from talos.logger import qiniu_logger
from qa.tasks.view import view_increase_amount
from qa.utils import const_strings
from qa.cache import (
    high_quality_question_cache,
    question_inviter_cache,
    complains_question_cache,
)
from qa.libs import get_media_extra_info, _get_content_text
from talos.services import UserService, get_user_from_context
from talos.portal import get_doctor_from_user_ids  # 引用的是 talos services doctor 下的方法
from talos.tools.vote_tool import VoteTool
from talos.cache.base import vote_cache
from talos.cache.base import fake_vote_cache
from communal.normal_manager import (
    tag_manager,
)
from talos.rpc import get_current_rpc_invoker
from communal.tasks import intelligent_push_task


@shared_task
def add_answer_view(answer_ids=[]):
    for answer_id in answer_ids:
        view_increase_amount(const_strings.ANSWER_VIEW, answer_id, 1)


@shared_task
def add_question_view(question_ids=[]):
    for question_id in question_ids:
        view_increase_amount(const_strings.QUESTION_VIEW, question_id, 1)


@shared_task
def add_questions_view(question_ids):
    for question_id in question_ids:
        if question_id['question']:
            view_increase_amount(const_strings.QUESTION_VIEW, question_id['question'], 1)
        if question_id['qa']:
            view_increase_amount(const_strings.ANSWER_VIEW, question_id['qa'], 1)


@shared_task
def fake_vote_to_answer(repeat_times, answer_id, force_push=False):
    user_ids = rpc_client['api/user/get_sleep_user'](number=repeat_times).unwrap()
    add_fake_vote_to_answer(user_ids, answer_id, force_push=force_push)


def add_fake_vote_to_answer(user_ids, answer_id, force_push=False):

    answer_fake_vote_key = "answer_fake_vote_{id}".format(id=answer_id)
    is_set = fake_vote_cache.set(answer_fake_vote_key, 1, nx=True, ex=30)
    if not is_set:
        return

    answer = Answer.objects.get(id=answer_id)

    push_url = gm_protocol.get_answer_list(answer=answer_id)
    content = _get_content_text(answer.content)
    content = (content[:25] + '...') if len(content) > 25 else content
    if not answer.is_online:
        return

    for user_id in user_ids:
        answer_vote, created = AnswerVote.objects.get_or_create(user=user_id, answer_id=answer.id, is_fake=True)
        if created:
            # 对作者增加点赞数
            rpc_client['api/person/incr_vote'](user_id=user_id).unwrap()
            vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True)
            vt_v1.receive_answer_vote(answer_vote.id)

            vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True)
            vt_v1.receive_answer_vote(answer_vote.id)

        if force_push:
            try:
                user_name = UserService.get_user_by_user_id(user_id).nickname
            except:
                logging_exception()
                return

            vt_v1 = VoteTool(vote_cache, answer.user_id, new_version=True)
            vt_v1.receive_answer_vote(answer_vote.id)

            vote_push(
                user_id=answer.user_id,
                push_url=push_url,
                alert=u'{}赞了你的回复{}'.format(user_name, content),
                push_type=AUTOMATED_PUSH.ANSWER_GET_VOTE
            )
    vote_count = AnswerVote.objects.filter(answer_id=answer.id).count()
    answer.like_num = vote_count
    answer.save()


def bayes_antispam(doc_id, doc_type, content):
    """
    is spam.
    :param doc_id: document id.
    :param doc_type: document type.
    :param content: content
    :return:
    """
    try:
        return rpc_client['antispam/classify'](doc_id=doc_id, doc_type=doc_type, content=content).unwrap()['spam']
    except RPCFaultException:
        return False
    except:
        logging_exception()
        return False


def yidun_antispam(text):
    """
    易盾反垃圾
    http://support.dun.163.com/antispam/api/#_1
    :param text:
    :return:
    """
    try:
        data = rpc_client['antispam/yidun'](text=text).unwrap()
    except RPCFaultException:
        return False
    if data['result']['action'] == 2:
        label = data['result']['labels'][0]['label']
        if label == 100:
            return SPAM_LABEL.EROTICISM
        elif label == 200:
            return SPAM_LABEL.ADVERTISE
        elif label == 400:
            return SPAM_LABEL.PROHIBIT
        elif label == 600:
            return SPAM_LABEL.ABUSE
        elif label == 700:
            return SPAM_LABEL.WATERING
        return False


@shared_task
def check_spam(pk, fields, cls_type):
    """
    check spam.
    :param pk:
    :param fields:
    :param cls:
    :return:
    """
    clsMap = {
        DocType.ANSWER: Answer,
        DocType.QUESTION: Question,
        DocType.COMMENT: AnswerReply,
    }

    cls = clsMap.get(cls_type)
    if not cls:
        return False

    try:
        instance = cls.objects.get(pk=pk)
    except cls.DoesNotExist:
        return False

    content = u""
    for field in fields:
        content += getattr(instance, field, u"")
    instance.spam_label = bayes_antispam(doc_id=pk, doc_type=cls_type, content=content)
    yidun_label = yidun_antispam(content)
    if yidun_label:
        instance.spam_label = yidun_label
    instance.save()


@shared_task
def build_high_quality_cache():
    """

    :return:
    """
    start_time = datetime.now() - timedelta(days=90)
    condition = Q(is_online=True) & Q(is_recommend=True) & Q(create_time__gt=start_time)
    total = Question.objects.filter(condition).count()
    offset = random.randint(0, total)
    ids = list(Question.objects.filter(condition).values_list('id', flat=True)[offset:offset + 100])
    random.shuffle(ids)
    high_quality_question_cache.set('high_quality', json.dumps(ids))


@shared_task
def build_inviter_pool():
    """
    邀请人列表池
    :return:
    """
    start_time = datetime.now() - timedelta(days=150)
    query = Q(is_online=True, level__gte=CONTENT_CLASS.FINE, create_time__gt=start_time)
    users = Answer.objects.filter(query).values("user", "create_time")

    user_dic = {}
    # 用于构建用来比较的数据结构 {user_id:{"id":user_id, "cnt": count, "create_time": datetime类型}}
    for user in users:
        uid = user["user"]
        if uid not in user_dic:
            user_dic[uid] = {"id": uid, "cnt": 1, "create_time": user["create_time"]}
        else:
            user_dic[uid]['cnt'] += 1
            if user["create_time"] > user_dic[uid]["create_time"]:
                user_dic[uid]['create_time'] = user["create_time"]

    user_list = list(filter(lambda x: x["cnt"] > settings.INVITER_LIMIT_FORM_ANSWER, user_dic.values()))
    user_list.sort(key=lambda user: (user["cnt"], user["create_time"]), reverse=True)
    user_ids = [user["id"] for user in user_list]  # 筛选完毕，满足需求的所有user_id
    #  剔除 医生 or 医院用户
    doctors = get_doctor_from_user_ids(user_ids)
    doctor_user_ids = [int(doctor.user_id) for doctor in doctors]
    user_ids = list(filter(lambda y: y not in doctor_user_ids, user_ids))

    #  通过请求 gaia 的方法，过滤掉马甲账号,需要先做一次预处理，user_is_puppet_dic:{"user_id": "is_puppet"}
    user_infos = rpc_client["api/user/get_fundamental_info_by_user_ids"](user_ids=user_ids).unwrap()
    user_is_puppet_dic = {user["id"]: user["is_puppet"] for user in user_infos}
    user_ids = list(filter(lambda user_id: not user_is_puppet_dic[user_id], user_ids))

    question_inviter_cache.set("question_inviter_pool", json.dumps(user_ids))


@shared_task
def time_push_to_invited_user():
    """
    定时推送给被邀请者
    :return:
    """
    #  数据池 每天下午五点到上一天下午五点，被邀请的用户未回答的问题。
    today = datetime.now().replace(hour=17, minute=0, second=0)
    last_day = today - timedelta(days=1)
    need_push_info = QuestionInviter.objects.filter(
        answer_id__isnull=True, invite_time__range=[last_day, today]).values("inviter").annotate(nums=Count("inviter"))

    for info in need_push_info:
        push_url = GmProtocol().get_webview(settings.BACKEND_API_HOST + settings.INVITE_QUESTION_LIST_PAGE)
        kwargs = {
            "user_ids": [info["inviter"]],
            "platform": ['android', 'iPhone'],
            "alert": u'{count}位用户邀请你来回答医美问题，赶紧去为他们解答哦~'.format(count=info["nums"]),
            "extra": {
                'type': PUSH_INFO_TYPE.GM_PROTOCOL,
                'msgType': 4,
                'pushUrl': push_url,
                'push_url': push_url,
            },
            'push_type': AUTOMATED_PUSH.INVITATION_TO_ANSWER,
            # "labels": {},  # 不知道是否需要埋点，先预留
        }
        push_task_to_user_multi(**kwargs)


@shared_task
def get_relation_college_tag_questions():
    """
    获取关联大学标签的所有问题id及，后台设置的小程序推荐问题id
    :return:
    """
    tag_info = rpc_client["api/tag/hera_search"](query="", tag_type_in=[TAG_TYPE.COLLEGE, ], is_online=True).unwrap()
    tag_ids = [int(tag.get("id")) for tag in tag_info]
    question_ids = QuestionTag.objects.filter(tag__in=tag_ids).values_list("question_id", flat=True).distinct()
    recommends = Question.objects.filter(id__in=question_ids, is_online=True, recommend_xiaochengxu=True).values_list(
        "id", flat=True)
    complains_question_cache.set("tag_ids", json.dumps(tag_ids))
    complains_question_cache.set("recommend", json.dumps(list(recommends)))


def push_to_question_provider(user_id, answer_id, eta=None, question_title=None, user_name=None):
    """
    push 给提出问题的用户
    :param user_id: 用户ID
    :param question_id: 问题ID
    :param eta:
    :param question_title:
    :param user_name:
    :return:
    """
    push_url = gm_protocol.get_answer_list(answer=answer_id)
    extra = {
        'type': PUSH_INFO_TYPE.GM_PROTOCOL,
        'msgType': 4,
        'pushUrl': push_url,
        'push_url': push_url,
    }
    push_task_to_user_multi(
        user_ids=[user_id], push_type=AUTOMATED_PUSH.QUESTION_POSTED_ANSWER,
        extra=extra,
        labels={'event_type': 'push', 'event': 'question_received_answer'},
        alert=u'{user_name} 刚刚回答了你的问题＂{question_title}＂'.format(
            user_name=user_name, question_title=question_title),
        eta=eta,
    )


@shared_task
def send_answer_on_time(sa_id, question_user_id, question_title, nick_name, push_time):
    send_answer = SendAnswer.objects.get(id=sa_id)
    if send_answer.status != SEND_ANSWER_STATUS.SUCCESS:
        Answer.objects.update_or_create(**send_answer.data)
        send_answer.status = SEND_ANSWER_STATUS.SUCCESS
        send_answer.save()
        push_to_question_provider(user_id=question_user_id,
                                  eta=push_time,
                                  question_title=question_title,
                                  user_name=nick_name)


@shared_task
def comment_push(answer_id, comment_id=None, user_id=None, author_name=None, content=None, is_commented_reply=None):
    """1、2级评论push统一走 demeter 防干扰push"""
    if not user_id:
        return {}
    user_ids = [user_id]
    if is_commented_reply:
        content_id = comment_id
        push_type = AUTOMATED_PUSH.COMMENT_RECEIVED_REPLY
    else:
        content_id = answer_id
        push_type = AUTOMATED_PUSH.ANSWER_RECEIVED_COMMENTS

    images = list(AnswerReplyImages.objects.using(settings.SLAVE_DB_NAME).filter(
        reply_id=comment_id,
    ).values_list('url', flat=True))
    push_image = images and Picture(images[0]).watermarked or ''
    push_url = gm_protocol.get_user_answer_list()
    alert = u'@{}：{}...'.format(author_name, content[:25])
    intelligent_push_task.apply_async(
        args=(
            content_id, user_ids, push_type,
            {
                'type': PUSH_INFO_TYPE.GM_PROTOCOL,
                'pushUrl': push_url,
                'push_url': push_url,
                'image': push_image,
                'push_image': push_image,
            }
        ),
        kwargs={
            "platform": None,
            "alert": alert,
            "others": {
                "title": "你收到了一条新评论",
                "alert": alert,
            },
            "labels": {
                'event_type': 'push',
                'event': 'received_qa_comments'
            },
        },
    )


@shared_task
def add_doctor_question(question_id):
    """添加医生关联的问题"""

    try:
        question = Question.objects.get(id=question_id, is_online=True)
    except Question.DoesNotExist:
        return

    if question.answer_num:
        return

    user = question.user
    if not user.current_city_id:
        return

    try:
        doctors = rpc_client["doctor/getdoctorinfo_bycityid"](city_id=user.current_city_id).unwrap()
        doctor_ids = [doctor.get("doctor_id") for doctor in doctors]
    except:
        logging_exception()
        return

    messages = []
    for doctor_id in doctor_ids:
        messages.append(DoctorMessageList(
            user_id=user.id,
            doctor_id=doctor_id,
            question=question
        ))
    DoctorMessageList.objects.bulk_create(messages)


@shared_task
def qa_image_add_base_info(images_list, params_info):
    """
    更新问答图片的基础信息
    :param images_list: []   不带后缀的完整图片地址链接
    :param params_info:  {"model": answer_image, "param_name": "answer_id", "id": 111}
    :return:
    """

    mapping_dic = {
        "question_image": (QuestionImage, "question_id"),
        "answer_image": (AnswerImage, "answer_id"),
    }

    model, param_name = mapping_dic.get(params_info.get("model", ""), (None, ""))
    _id = params_info.get("id", 0)

    if model:
        _image_list = get_media_extra_info(images_list)
        for image_dic in _image_list:
            if param_name:
                _kw = {
                    "image_url_source": MEDIA_IMAGE_URL_SOURCE.RICH_TEXT,
                    "image_url": image_dic.get("image_url", ""),
                    param_name: _id,
                }

                _default = {
                    "width": image_dic.get("width", 0),
                    "height": image_dic.get("height", 0),
                }

                model.objects.get_or_create(**_kw, defaults=_default)
            else:
                continue


@shared_task
def applet_replied_push(answer_reply_id):
    """
    回答的评论被评论，给回答评论的用户 发送小程序推送  自己给自己评论无效
    回答被评论，给回答的用户发   自己给自己评论无效
    :param answer_reply_id: 评论id
    :return:
    """

    if not answer_reply_id:
        return

    try:
        answer_reply = AnswerReply.objects.get(id=answer_reply_id)
    except AnswerReply.DoesNotExist:
        return

    reply_content = answer_reply.content[:20]

    nickname = answer_reply.user.nickname[:10]

    data = {
        "name1": {
            "value": nickname
        },
        "thing2": {
            "value": reply_content
        },
        "date3": {
            "value": "{date}".format(date=datetime.now().strftime('%Y年%m月%d日 %H:%M'))
        },
        "thing4": {
            "value": "点击快速查看>>"
        }
    }

    # 模板id
    template_id = settings.APPLET_SUBSCRIBE_MSG.get("comment", "")

    # 跳转页面
    page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \
           'comment_id={comment_id}&from={from_page}&from_action={from_action}'.format(
        answer_id=answer_reply.answer_id,
        comment_id=answer_reply.id,
        from_page=APPLET_PAGE_FROM.CARD,
        from_action=APPLET_SUBSCRIBE_MSG_TYPE.COMMENT
    )

    # 给回答用户发
    answer_user_id = answer_reply.answer.user_id
    if answer_reply.user_id != answer_user_id:
        send_applet_subscribe_msg(answer_user_id, template_id, data=data, page=page)

    if not answer_reply.commented_reply_id:
        return
    try:
        commented_answer_reply = AnswerReply.objects.get(id=answer_reply.commented_reply_id)
    except AnswerReply.DoesNotExist:
        return

    # 给一级评论用户发
    if answer_reply.commented_reply_id != answer_reply.first_reply_id:
        try:
            level_1_reply = AnswerReply.objects.get(id=answer_reply.first_reply_id)
        except:
            level_1_reply = None

        if level_1_reply:
            # 自己给自己评论无效
            if answer_reply.user_id != level_1_reply.user_id:
                # 发送小程序推送
                send_applet_subscribe_msg(level_1_reply.user_id, template_id, data=data, page=page)

    # 自己给自己评论无效
    if answer_reply.user_id == commented_answer_reply.user_id:
        return

    # 发送小程序推送
    send_applet_subscribe_msg(commented_answer_reply.user_id, template_id, data=data, page=page)


@shared_task
def applet_reply_summary_push(answer_reply_id):
    """
    用户评论完24小时后，
    如果没有收到评论或点赞，则给用户推送回答的新增评论总数，或回答的相关内容
    如果被赞，且被赞数大于1，则推送新增被赞数
    :param answer_reply_id: 当前评论id
    :return:
    """
    if not answer_reply_id:
        return

    try:
        answer_reply = AnswerReply.objects.get(id=answer_reply_id)
    except AnswerReply.DoesNotExist:
        return

    user_id = answer_reply.user_id

    new_answer_reply = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\
        filter(id__gt=answer_reply_id, user=user_id, is_online=True).exists()

    if new_answer_reply:
        return

    replied_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\
        filter(commented_reply_id=answer_reply_id, is_online=True).exclude(user=user_id).count()
    voted_count = AnswerVoteReply.objects.using(settings.SLAVE_DB_NAME).\
        filter(answerreply_id=answer_reply_id).exclude(user=user_id).count()
    answer_content =Answer.objects.filter(id=answer_reply.answer_id).first().content
    answer_content = _get_content_text(answer_content)[:10]

    # 当前评论有被评论或被赞
    if replied_count or voted_count:
       return

    answer_id = answer_reply.answer_id

   # 回答新增一级评论数（不包含自己的）
    additional_reply_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).\
        filter(id__gt=answer_reply_id, answer_id=answer_id, first_reply__isnull=True, is_online=True).\
        exclude(user=user_id).count()

    # 有新增评论，发送24小内新增评论总数
    if additional_reply_count:
        data = {
            "thing1": {
                "value": answer_content
            },
            "thing2": {
                "value": "你评论的回答，新增{reply_count}条吐槽，立即查看".format(reply_count=additional_reply_count)[:20]
            }
        }

        # 模板id
        template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "")

        # 跳转页面
        page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \
               'from={from_page}&from_action={from_action}'.format(
            answer_id=answer_reply.answer_id,
            from_page=APPLET_PAGE_FROM.CARD,
            from_action=APPLET_SUBSCRIBE_MSG_TYPE.NEW_COMMENT
        )

    # 无新增评论，推送评论的帖子的相同标签下的其它内容详情页
    else:
        data = {
            "thing2": {
                "value": answer_content
            },
            "thing4": {
                "value": "亲！你关注过的话题又有新内容啦>>"
            }
        }

        # 模板id
        template_id = settings.APPLET_SUBSCRIBE_MSG.get("recommend", "")

        # 获取当前回答的标签
        tag_id_list = AnswerTag.objects.filter(answer_id=answer_id).values_list('tag', flat=True)
        tag_info = list(tag_manager.get_tags_info_by_ids(tag_id_list).values())
        tag_name = tag_info and tag_info[0] and tag_info[0].get("tag_name")

        if not tag_name:
            return

        # 调策略 获取相关内容
        def get_new_answer_id(rpc_client, offset, tag_name):
            res = rpc_client['doris/query/answer'](sort_type=DIARY_ORDER_TYPE.DEFAULT, query=tag_name, size=1,
                                                   offset=offset).unwrap()
            new_answer_id = res and res.get("answer_ids") and res.get("answer_ids")[0]
            return new_answer_id

        rpc_client = get_current_rpc_invoker()
        offset = random.randint(0, 200)
        origin_offset = offset
        new_answer_id = None
        num = 6
        while not new_answer_id and num:
            try:
                new_answer_id = get_new_answer_id(rpc_client, offset, tag_name)
            except:
                new_answer_id = None
            offset = origin_offset % num
            if num > 1:
                offset += random.randint(0, 10)
            num -= 1

        if not new_answer_id:
            return

        # 跳转页面
        page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \
               'from={from_page}&from_action={from_action}'.format(
            answer_id=new_answer_id,
            from_page=APPLET_PAGE_FROM.CARD,
            from_action=APPLET_SUBSCRIBE_MSG_TYPE.RELATED_CONTENT
        )

    # 发送小程序推送
    send_applet_subscribe_msg(user_id, template_id, data=data, page=page)


@shared_task
def applet_voted_push(answer_reply_vote_id):
    """
    回答的评论被点赞，给回答评论的用户 发送小程序推送  自己给自己点赞无效
    :param answer_reply_id: 评论id
    :return:
    """

    if not answer_reply_vote_id:
        return

    try:
        answer_reply_vote = AnswerVoteReply.objects.get(id=answer_reply_vote_id)
    except AnswerVoteReply.DoesNotExist:
        return

    try:
        answer_reply = AnswerReply.objects.get(id=answer_reply_vote.answerreply_id, is_online=True)
    except AnswerReply.DoesNotExist:
        return

    # 自己给自己点赞不用发
    if answer_reply_vote.user_id == answer_reply.user_id:
        return

    answer_content = Answer.objects.filter(id=answer_reply.answer_id).first().content
    answer_content =  _get_content_text(answer_content)[:10]

    data = {
        "thing1": {
            "value": answer_content
        },
        "thing2": {
            "value": "你的评论收到了新的支持，快来看看吧>>"
        }
    }

    # 模板id
    template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "")

    # 跳转页面
    page = '/packageBBS/pages/ask/answerDetail/answerDetail?answerId={answer_id}&' \
           'comment_id={comment_id}&from={from_page}&from_action={from_action}'.format(
        answer_id=answer_reply.answer_id,
        comment_id=answer_reply.id,
        from_page=APPLET_PAGE_FROM.CARD,
        from_action=APPLET_SUBSCRIBE_MSG_TYPE.VOTE
    )

    # 发送小程序推送
    send_applet_subscribe_msg(answer_reply.user_id, template_id, data=data, page=page)


@shared_task
def applet_answer_summary_push(answer_id):
    """
    用户回答完24小时后，
    如果没有收到评论或点赞，则给用户推送问题的新增回答总数，或问题的相关内容
    如果被赞，且被赞数大于1，则推送新增被赞数
    :param answer_reply_id: 当前评论id
    :return:
    """
    if not answer_id:
        return

    try:
        answer_info = Answer.objects.get(id=answer_id)
    except Answer.DoesNotExist:
        return

    user_id = answer_info.user_id

    new_answer = Answer.objects.using(settings.SLAVE_DB_NAME).\
        filter(id__gt=answer_id, user=user_id, is_online=True).exists()

    if new_answer:
        return

    replied_count = AnswerReply.objects.using(settings.SLAVE_DB_NAME).filter(answer_id=answer_id, is_online=True).\
        exclude(user=user_id).count()
    voted_count = AnswerVote.objects.using(settings.SLAVE_DB_NAME).filter(answer_id=answer_id).\
        exclude(user=user_id).count()

    answer_content =  _get_content_text(answer_info.content)[:10]

    # 当前回答有被评论或被赞
    if replied_count or voted_count:
        return

    question_id = answer_info.question_id

   # 问题新增回答数（不包含自己的）
    additional_answer_count = Answer.objects.using(settings.SLAVE_DB_NAME).\
        filter(id__gt=answer_id, question_id=question_id, is_online=True).exclude(user=user_id).count()

    # 有新增回答，发送24小内新增回答总数
    if additional_answer_count:
        data = {
            "thing1": {
                "value": answer_content
            },
            "thing2": {
                "value": "你评论的问题，新增{reply_count}条吐槽，立即查看".format(reply_count=additional_answer_count)[:20]
            }
        }

        # 模板id
        template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "")

        # 跳转页面
        page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&' \
               'from={from_page}&from_action={from_action}'.format(
            question_id=answer_info.question_id,
            from_page=APPLET_PAGE_FROM.CARD,
            from_action=APPLET_SUBSCRIBE_MSG_TYPE.NEW_COMMENT
        )

    # 无新增回答，推送回答的问题的相同标签下的其它内容详情页
    else:
        data = {
            "thing2": {
                "value": answer_content
            },
            "thing4": {
                "value": "亲！你关注过的话题又有新内容啦>>"
            }
        }

        # 模板id
        template_id = settings.APPLET_SUBSCRIBE_MSG.get("recommend", "")

        # 获取当前问题的标签
        tag_id_list = QuestionTag.objects.filter(question_id=question_id).values_list('tag', flat=True)
        tag_info = list(tag_manager.get_tags_info_by_ids(tag_id_list).values())
        tag_name = tag_info and tag_info[0] and tag_info[0].get("tag_name")
        if not tag_name:
            return

        # 获取相关问题内容
        def get_new_question_id(rpc_client, offset):
            res = rpc_client['doris/search/question'](query=tag_name, size=1, offset=offset,
                                                      sort_type=QUESTION_ORDER_TYPE.DEFAULT).unwrap()
            new_question_id = res and res.get("question_ids") and res.get("question_ids")[0]
            return new_question_id

        rpc_client = get_current_rpc_invoker()
        offset = random.randint(0, 200)
        origin_offset = offset
        new_question_id = None
        num = 6
        while not new_question_id and num:
            try:
                new_question_id = get_new_question_id(rpc_client, offset)
            except:
                new_question_id = None
            offset = origin_offset % num
            if num > 1:
                offset += random.randint(0, 10)
            num -= 1

        if not new_question_id:
            return

        #  跳转页面
        page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&' \
               'from={from_page}&from_action={from_action}'.format(
            question_id=new_question_id,
            from_page=APPLET_PAGE_FROM.CARD,
            from_action=APPLET_SUBSCRIBE_MSG_TYPE.RELATED_CONTENT
        )

    # 发送小程序推送
    send_applet_subscribe_msg(user_id, template_id, data=data, page=page)


@shared_task
def applet_answer_voted_push(answer_vote_id):
    """
    回答被点赞，给回答的用户 发送小程序推送  自己给自己点赞无效
    :param answer_reply_id: 评论id
    :return:
    """

    if not answer_vote_id:
        return

    try:
        answer_vote = AnswerVote.objects.get(id=answer_vote_id, is_fake=False)
    except AnswerVote.DoesNotExist:
        return

    try:
        answer_info = Answer.objects.get(id=answer_vote.answer_id, is_online=True)
    except AnswerReply.DoesNotExist:
        return

    # 自己给自己点赞不用发
    if answer_vote.user_id == answer_info.user_id:
        return

    answer_content = _get_content_text(answer_info.content)[:10]

    data = {
        "thing1": {
            "value": answer_content
        },
        "thing2": {
            "value": "你的评论收到了新的支持，快来看看吧>>"
        }
    }

    # 模板id
    template_id = settings.APPLET_SUBSCRIBE_MSG.get("vote", "")

    # 跳转页面
    page = '/packageBBS/pages/ask/questionDetail/questionDetail?questionId={question_id}&answer_id={answer_id}&' \
           'from={from_page}&from_action={from_action}'.format(
        answer_id=answer_info.id,
        question_id=answer_info.question_id,
        from_page=APPLET_PAGE_FROM.CARD,
        from_action=APPLET_SUBSCRIBE_MSG_TYPE.VOTE
    )

    # 发送小程序推送
    send_applet_subscribe_msg(answer_info.user_id, template_id, data=data, page=page)
