#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 社交相关的东西
# 问题回答数，浏览量，回答评论数，点赞状态……
from __future__ import unicode_literals, absolute_import, print_function

from django.db.models import Count, Q

from qa.cache import ViewRecord
from qa.models.answer import (
    Answer,
    AnswerVote,
    AnswerFavor,
    AnswerReply,
    QuestionFavor,
)
from qa.utils import const_strings  # view_record model type


class QaSocialService(object):
    """
    问答社交相关的逻辑
    """

    def get_answer_num_by_question_ids(self, question_ids):
        """
        通过问题id获取回答数量
        :param question_ids:
        :return: {question_id: num}
        """
        _nums = Answer.objects.filter(
            question_id__in=question_ids,
            is_online=True
        ).values("question_id").annotate(cnt=Count("question_id")).values("question_id", "cnt")

        result = {}
        for item in _nums:
            result[item["question_id"]] = item["cnt"]

        return result

    def get_answer_is_voted_by_answer_ids(self, answer_ids, viewer_user_id=None):
        """
        获取用户点赞状态
        :param answer_ids:
        :param viewer_user_id:
        :return:
        """
        result = {}
        if not all([answer_ids, viewer_user_id]):
            return result

        avs = list(AnswerVote.objects.filter(
            answer_id__in=answer_ids,
            user=viewer_user_id,
            is_fake=False,
        ).values_list("answer_id", flat=True))

        if avs:
            result = {av: True for av in avs}

        return result

    def get_answer_is_favored_by_answer_ids(self, answer_ids, viewer_user_id=None):
        """
        获取回答关注状态
        :param answer_ids:
        :param viewer_user_id:
        :return:
        """
        result = {}
        if not all([answer_ids, viewer_user_id]):
            return result

        avs = list(AnswerFavor.objects.filter(
            answer_id__in=answer_ids,
            user_id=viewer_user_id,
            is_online=True,
        ).values_list("answer_id", flat=True))

        if avs:
            result = {av: True for av in avs}

        return result

    def get_question_is_favored_by_question_ids(self, question_ids, viewer_user_id=None):
        """
        获取问题关注状态
        :param question_ids:
        :param viewer_user_id:
        :return:
        """
        result = {}
        if not all([question_ids, viewer_user_id]):
            return result

        avs = list(QuestionFavor.objects.filter(
            question_id__in=question_ids,
            user_id=viewer_user_id,
            is_online=True,
        ).values_list("question_id", flat=True))

        if avs:
            result = {av: True for av in avs}

        return result

    def get_answer_reply_nums_by_answer_ids(self, answer_ids):
        """
        通过回答id获取评论数
        :param answer_ids:
        :return:
        """
        result = {}
        if not answer_ids:
            return result

        def _get_nums_func(query):
            _nums = AnswerReply.objects.filter(
                query
            ).values("answer_id").annotate(cnt=Count("answer_id")).values("answer_id", "cnt")

            return {num["answer_id"]: num["cnt"] for num in _nums}

        base_query = Q(is_online=True, answer_id__in=answer_ids)

        # 总评论数
        answer_comment_nums = _get_nums_func(base_query)
        # 一级评论数
        _query = base_query & Q(commented_reply_id__isnull=True)
        answer_first_reply_nums = _get_nums_func(_query)

        for answer_id in answer_ids:
            result[answer_id] = {
                "comment_num": answer_comment_nums.get(answer_id, 0),
                "first_reply_num": answer_first_reply_nums.get(answer_id, 0),
            }

        return result

    def get_amounts_from_redis(self, qa_ids, const_string):
        """
        批量从缓存中获取数量
        :param qa_ids: 问答id
        :param const_string: 存储类型 const_strings.ANSWER_VIEW
        :return:
        """
        result = {}

        qa_ids = list(set(filter(None, qa_ids)))
        if not all([qa_ids, const_string]):
            return result

        view_record = ViewRecord(const_string)
        _nums = view_record.view_hmget(qa_ids)

        for _id, _num in zip(qa_ids, _nums):
            result[_id] = _num and int(_num) or 0

        return result
