import random
from itertools import chain

from django.conf import settings

from communal.models.fake_reply import FakeReplyConfig, FakeReplyPool, FakeReplyConfigMapReply
from talos.cache.base import fake_cache
from talos.rpc import get_current_rpc_invoker

call_rpc = get_current_rpc_invoker()


class FakeCacheService(object):
    @classmethod
    def generate_cache_key(cls, content_type, content_id):
        return "{}:{}".format(content_type, content_id)

    @classmethod
    def cache_reply(cls, content_type, content_id, reply_id):
        key = cls.generate_cache_key(content_type, content_id)
        fake_cache.sadd(key, reply_id)

    @classmethod
    def get_all_cached_ids(cls, content_type, content_id):
        key = cls.generate_cache_key(content_type, content_id)
        ids = fake_cache.smembers(key)

        return set(map(int, ids))


class FakeService(object):

    @classmethod
    def get_fake_reply_ids_by_tag_ids(cls, tag_ids):
        """
        根据标签/标签大组获取评论
        :param tag_ids:
        :return:
        """
        if not tag_ids:
            return []
        config_ids = list(FakeReplyConfig.objects.using(settings.SLAVE_DB_NAME).filter(
            tag_id__in=tag_ids, is_online=True).values_list('id', flat=True))
        reply_ids = list(FakeReplyConfigMapReply.objects.using(settings.SLAVE_DB_NAME).filter(
            config_id__in=config_ids).values_list('reply_id', flat=True))
        comment_ids = list(FakeReplyPool.objects.using(settings.SLAVE_DB_NAME).filter(
            id__in=reply_ids, is_online=True,
        ).values_list('id', flat=True))
        if not comment_ids:
            try:
                tag_category_map = call_rpc["api/tag_v3/list_group_by_tags"](tag_ids=tag_ids).unwrap()
            except:
                return []
            tag_category_ids = [item.get('id', 0) for item in chain(*tag_category_map.values())]
            config_ids = list(FakeReplyConfig.objects.filter(
                tag_group_id__in=tag_category_ids, is_online=True).values_list('id', flat=True))
            reply_ids = list(FakeReplyConfigMapReply.objects.using(settings.SLAVE_DB_NAME).filter(
                config_id__in=config_ids).values_list('reply_id', flat=True))
            comment_ids = list(FakeReplyPool.objects.filter(
                id__in=reply_ids, is_online=True).values_list('id', flat=True))

        return comment_ids

    @classmethod
    def get_comment_by_tag_ids(cls, tag_ids, content_type, content_id):
        """
        通过新标签获取 灌水评论
        :return:
        """
        related_replies = cls.get_fake_reply_ids_by_tag_ids(tag_ids)
        cached_ids = FakeCacheService.get_all_cached_ids(content_type, content_id)
        cached_ids = set(map(int, cached_ids))
        not_used_ids = list(set(related_replies) - cached_ids)
        if not not_used_ids:
            return None
        reply_id = random.choice(not_used_ids)
        reply = FakeReplyPool.objects.get(id=reply_id)
        FakeCacheService.cache_reply(content_type, content_id, reply_id)

        return reply.content
