# coding:utf-8

from datetime import datetime
import json

from collections import defaultdict
from django.conf import settings
from celery import shared_task
from gm_types.doris import CONTENT_AGGRE_CARD_TYPE

from gm_types.gaia import (
    PLATFORM_CHOICES,
    GROUP_TOPIC_TYPE,
    TOP_CONTENT_RELATED_TYPE)

from rpc.tool.log_tool import info_logger, logging_exception
from rpc.tool.protocol import gm_protocol
from gm_types.push import (
    PUSH_INFO_TYPE,
    AUTOMATED_PUSH,
)

from api.tasks.push_task import automate_push_task
from group.tasks.follow_push import GroupFollowPush
from group.models import Group, GroupTopicRelation, Topic
from group.service import TopicService, GroupService
from rpc.all import get_rpc_remote_invoker
from rpc.cache import group_cache

GROUP_INFO_KEY = 'group:{}:extra_info'
TOPIC_INFO_KEY = 'topic:{}:extra_info'
# 前100条内容总评论
doris_feeds_100 = "doris/search/group_feed_recall"  # res: {"group_feeds_id: [], "total_number": 123}
# 内容总数量
doris_content_count = "doris/search/hit_billboard_get_total"


@shared_task
def group_follower_push():

    today = datetime.now().strftime("%Y%m%d")

    data = GroupFollowPush.get_content_by_ids()
    for item in data:
        group_id = item["group_id"]
        content_type = item["type"]
        content_id = item["id"]

        followers = GroupFollowPush.get_group_follows_by_id(group_id)
        followers = map(str, followers)
        hash_pushed_users = GroupFollowPush.get_pushed_users(group_id, content_type, content_id, today)
        push_users = list(set(followers) - set(hash_pushed_users))

        if not push_users:
            continue

        push_msg = GroupFollowPush.get_push_msg(content_type, content_id)
        if not push_msg:
            continue

        alert = push_msg["content"]
        if not alert:
            info_logger.info('group_id:{}, content_type:{}, content_id:{}未推送'.format(
                group_id, content_type, content_id
            ))
        push_url = gm_protocol.get_group_detail(group_id, activity_type=item.get("group_type", GROUP_TOPIC_TYPE.COMMON))
        kwargs = {
            "user_ids": push_users,
            "push_type": AUTOMATED_PUSH.PAYMENT_REFUNDED,
            "platform": [PLATFORM_CHOICES.ANDROID, PLATFORM_CHOICES.IPHONE],
            "extra": {
                "type": PUSH_INFO_TYPE.GM_PROTOCOL,
                "pushUrl": push_url,
                "push_url": push_url,
            },
            "alert": alert,
        }

        title = push_msg["title"]
        if title:
            kwargs["others"] ={
                "title": title,
                "alert": alert,
            }

        automate_push_task(**kwargs)

        GroupFollowPush.record_push_users(group_id, content_type, content_id, push_users, today)
    GroupFollowPush.del_pushed_user_key()


@shared_task
def sort_group_topic():
    """排序小组下面的话题。

    小组下面的话题排序根据召回的第一个数据的时间顺序进行排序。
    """

    rpc = get_rpc_remote_invoker()
    endpoint = "doris/search/group_topic_sort"

    for group in Group.objects.using(settings.SLAVE_DB_NAME).all():

        topics_newtime = {}
        topic_ids = GroupTopicRelation.objects.using(settings.SLAVE_DB_NAME).filter(group_id=group.id).values_list("topic_id", flat=True)
        for topic_id in topic_ids:
            tags = TopicService.tags_by_topic_id(topic_id)
            try:
                res = rpc[endpoint](
                    current_tag=[item["id"] for item in tags["tags"]],
                    sun_tag=[item["id"] for item in tags["children"]],
                    parent_tag=[item["id"] for item in tags["parent"]],
                    tags_v3=[item["id"] for item in tags["tags_v3"]],
                ).unwrap()
            except:
                continue

            first_time = res["group_topic_newtime"]
            if not first_time:
                continue

            topics_newtime[topic_id] = first_time

        # 按时间倒序排，最新的在前面
        sort_topic_ids = [item[0] for item in sorted(topics_newtime.items(), key=lambda i: -i[1])]
        group_cache.set(TopicService.group_topic_rank_key_tpl.format(group_id=group.id), json.dumps(sort_topic_ids))


class GroupTopicExtraSync(object):

    @classmethod
    def get_group_topic_reply_count(cls, polymer_id, _type):
        if _type == TOP_CONTENT_RELATED_TYPE.GROUP:
            tags = GroupService.tags_by_group_id(polymer_id)
        else:
            tags = TopicService.tags_by_topic_id(polymer_id)
        try:
            rpc = get_rpc_remote_invoker()
            params = {
                "current_tag": [item["id"] for item in tags["tags"]],
                "sun_tag": [item["id"] for item in tags["children"]],
                "parent_tag": [item["id"] for item in tags["parent"]],
                "tags_v3": [item["id"] for item in tags["tags_v3"]],
                "size": 100,
                "offset": 0,
                "device_id": '123456789',  # 必传 一个不存在的设备号
                "choose_type": 2,
                "use_tagv3": True,
            }
            res = rpc[doris_feeds_100](
                **params
            ).unwrap()
            res.update({'type': _type, 'id': polymer_id})
            info_logger.info("params: {}, res: {}".format(params, json.dumps(res)))
        except:
            logging_exception()
            return {}

        contents = res.get('group_feed_ids', [])
        content_count = res.get("total_number", 0)
        diary, answer, tractate = [], [], []
        for content in contents:
            if content['type'] == CONTENT_AGGRE_CARD_TYPE.DIARY:
                diary.append(content['id'])
            elif content['type'] == CONTENT_AGGRE_CARD_TYPE.TRACTATE:
                tractate.append(content['id'])
            elif content['type'] == CONTENT_AGGRE_CARD_TYPE.ANSWER:
                answer.append(content['id'])
        try:
            rpc = get_rpc_remote_invoker()
            data = rpc['mimas/group/reply_count'](
                diary_ids=diary, answer_ids=answer, tractate_ids=tractate
            ).unwrap()
            info_logger.info(json.dumps(data))
        except:
            logging_exception()
            data = {}
        data['content_count'] = content_count
        return data

    @classmethod
    def get_group_topic_content_count(cls, polymer_id, _type):
        if _type == TOP_CONTENT_RELATED_TYPE.GROUP:
            tags = GroupService.tags_by_group_id(polymer_id)
        else:
            tags = TopicService.tags_by_topic_id(polymer_id)
        try:
            rpc = get_rpc_remote_invoker()
            res = rpc[doris_content_count](
                current_tag=[item["id"] for item in tags["tags"]],
                sun_tag=[item["id"] for item in tags["children"]],
                parent_tag=[item["id"] for item in tags["parent"]],
                tagv3_data=[{
                    'tag_id': item["id"],  # v7.29.0 调整，配合策略传参
                    'name': item["name"],
                    'tag_type': item['tag_type'],
                } for item in tags["tags_v3"]],
                use_tagv3=True,
            ).unwrap()
            info_logger.info(json.dumps(res))
        except:
            logging_exception()
            return {}
        return res


@shared_task
def topic_group_content_info():
    """
    统计小组、话题下评论、内容数量
    :return:
    """

    # 小组获取评论总数/内容总数
    for group in Group.objects.using(settings.SLAVE_DB_NAME).all():
        group_key = GROUP_INFO_KEY.format(group.id)
        total = GroupTopicExtraSync.get_group_topic_reply_count(group.id, _type=TOP_CONTENT_RELATED_TYPE.GROUP)
        # content_count = GroupTopicExtraSync.get_group_topic_content_count(
        # group.id, _type=TOP_CONTENT_RELATED_TYPE.GROUP)
        group_dic = {
            'reply_count': total.get('total_count', 0),
            'content_count': total.get('content_count', 0)
        }
        group_cache.set(group_key, json.dumps(group_dic))

    # 话题获取评论总数/内容总数
    for topic in Topic.objects.using(settings.SLAVE_DB_NAME).all():
        topic_key = TOPIC_INFO_KEY.format(topic.id)
        total = GroupTopicExtraSync.get_group_topic_reply_count(topic.id, _type=TOP_CONTENT_RELATED_TYPE.TOPIC)
        # content_count = GroupTopicExtraSync.get_group_topic_content_count(
        # topic.id, _type=TOP_CONTENT_RELATED_TYPE.TOPIC)
        topic_dic = {
            'reply_count': total.get('total_count', 0),
            'content_count': total.get('content_count', 0)
        }
        group_cache.set(topic_key, json.dumps(topic_dic))


@shared_task
def sync_group_topic_extra_by_id(polymer_id, _type):
    if _type == TOP_CONTENT_RELATED_TYPE.GROUP:
        group_key = GROUP_INFO_KEY.format(polymer_id)
        total = GroupTopicExtraSync.get_group_topic_reply_count(polymer_id, _type=_type)
        # content_count = GroupTopicExtraSync.get_group_topic_content_count(polymer_id, _type=_type)
        group_dic = {
            'reply_count': total.get('total_count', 0),
            'content_count': total.get('content_count', 0)
        }
        group_cache.set(group_key, json.dumps(group_dic))
    elif _type == TOP_CONTENT_RELATED_TYPE.TOPIC:
        topic_key = TOPIC_INFO_KEY.format(polymer_id)
        total = GroupTopicExtraSync.get_group_topic_reply_count(polymer_id, _type=_type)
        # content_count = GroupTopicExtraSync.get_group_topic_content_count(polymer_id, _type=_type)
        topic_dic = {
            'reply_count': total.get('total_count', 0),
            'content_count': total.get('content_count', 0)
        }
        group_cache.set(topic_key, json.dumps(topic_dic))
