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

from gm_types.gaia import VOTEOBJECT
from django.utils import timezone

from talos.libs.datetime_utils import get_timestamp_or_none
from talos.models.diary import Diary, DiaryVote
from talos.models.topic import TopicVote, TopicReplyVote

from qa.portal import (
    get_unread_answer_vote_num_by_user_id,
    get_unread_answer_reply_vote_num_by_user_id,
    get_answer_vote_infos_by_ids,
)
from talos.models.tractate import TractateReplyVote, Tractate, TractateVote


class VoteTool(object):
    """vote tool for user.

    add vote info into ssdb, if user's topic/diary received new vote.
    """

    def __init__(self, redis_c, user_id, new_version=False):
        self.user_id = user_id
        self.redis_c = redis_c

        self._diary_vote_key_prefix = 'd:'
        self._topic_vote_key_prefix = 't:'
        self._tractate_vote_key_prefix = 'tv:'  # 新帖子点赞
        self._tractate_reply_vote_key_prefix = 'trv:'  # 新帖子回复点赞
        self._soft_article_vote_key_prefix = 'sv:'       #医生后台帖子点赞
        self._soft_article_reply_vote_key_prefix = 'srv:'    #医生后台帖子回复点赞
        self._answer_vote_key_prefix = 'a:'
        self._answer_reply_vote_key_prefix = 'ar:'
        self._topic_reply_vote_key_prefix = 'tr:'

        if not new_version:
            self._vote_key_prefix_format = 'user:{user_id}:votes:received'
        else:
            self._vote_key_prefix_format = 'user:{user_id}:votes:received:v1'

        self._k = self._vote_key_prefix_format.format(user_id=user_id)

    def _cache_this(self, k, vote_time):

        if not vote_time:
            vote_time = timezone.now()

        score = get_timestamp_or_none(vote_time)
        self.redis_c.zadd(self._k, score, k)

    def receive_diary_vote(self, diaryvote_id, vote_time=None):
        v = self._diary_vote_key_prefix
        v = v + str(diaryvote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_topic_vote(self, topicvote_id, vote_time=None):
        v = self._topic_vote_key_prefix
        v = v + str(topicvote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_tractate_vote(self, tractate_vote_id, vote_time=None):
        v = self._tractate_vote_key_prefix
        v = v + str(tractate_vote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_tractate_reply_vote(self, reply_vote_id, vote_time=None):
        v = self._tractate_reply_vote_key_prefix
        v = v + str(reply_vote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_soft_article_vote(self, soft_article_vote_id, vote_time=None):
        v = self._soft_article_vote_key_prefix
        v = v + str(soft_article_vote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_soft_article_reply_vote(self, reply_vote_id, vote_time=None):
        v = self._soft_article_reply_vote_key_prefix
        v = v + str(reply_vote_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_answer_vote(self, answer_id, vote_time=None):
        v = self._answer_vote_key_prefix
        v = v + str(answer_id)
        self._cache_this(v, vote_time=vote_time)

    def remove_answer_vote(self, answer_id):
        v = self._answer_vote_key_prefix + str(answer_id)
        self._del_cache(v)

    def receive_answer_reply_vote(self, reply_id, vote_time=None):
        v = self._answer_reply_vote_key_prefix + str(reply_id)
        self._cache_this(v, vote_time=vote_time)

    def receive_topic_reply_vote(self, topicreplyvote_id, vote_time=None):
        v = self._topic_reply_vote_key_prefix
        v = v + str(topicreplyvote_id)
        self._cache_this(v, vote_time=vote_time)

    def get_votes_received(self, start_num=0, count=10):
        """return list of tuple as [(id, type), ]"""
        result = self.redis_c.zrevrange(self._k, start_num, start_num + count - 1)
        if not result:
            return []

        res = []
        for r in result:
            t, v = r.decode("utf-8").split(':')   # 数据类型，byte -> str
            t += ':'  # hmmm,,,
            if t == self._diary_vote_key_prefix:
                res.append((v, VOTEOBJECT.DIARY))

            elif t == self._topic_vote_key_prefix:
                res.append((v, VOTEOBJECT.TOPIC))

            elif t == self._answer_vote_key_prefix:
                res.append((v, VOTEOBJECT.ANSWER))

            elif t == self._answer_reply_vote_key_prefix:
                res.append((v, VOTEOBJECT.ANSWER_REPLY))

            elif t == self._topic_reply_vote_key_prefix:
                res.append((v, VOTEOBJECT.TOPIC_REPLY))

            elif t == self._tractate_vote_key_prefix:
                res.append((v, VOTEOBJECT.TRACTATE))

            elif t == self._tractate_reply_vote_key_prefix:
                res.append((v, VOTEOBJECT.TRACTATE_REPLY))

            elif t == self._soft_article_reply_vote_key_prefix:    # 新增医生短文评论点赞类型
                res.append((v, VOTEOBJECT.DOCTOR_ARTICLE_REPLY))

        return res

    def get_vote_count(self):
        return self.redis_c.zcard(self._k)

    def _del_cache(self, v):
        self.redis_c.zrem(self._k, v)

    def remove_tractate_vote(self, tractate_vote_id):
        v = self._tractate_vote_key_prefix + str(tractate_vote_id)
        self._del_cache(v)

    def remove_tractate_reply_vote(self, tractate_reply_id):
        v = self._tractate_reply_vote_key_prefix + str(tractate_reply_id)
        self._del_cache(v)

    def remove_soft_article_vote(self, soft_article_vote_id):
        v = self._soft_article_vote_key_prefix + str(soft_article_vote_id)
        self._del_cache(v)

    def remove_soft_article_reply_vote(self, soft_article_reply_vote_id):
        v = self._soft_article_reply_vote_key_prefix + str(soft_article_reply_vote_id)
        self._del_cache(v)


def get_unread_vote_num_by_user_id(user_id, add_answer=False):
    """
    通过user_id 获取当前用户未读得点赞总数
    :param user_id: 当前用户id
    :param add_answer: 是否增加回答的未读点赞数
    :return: int count
    """
    count = 0
    if not user_id:
        return count

    unread_num = TopicVote.objects.filter(
        topic_author_id=user_id,
        unread=True
    ).count()
    count += unread_num

    my_diaries = Diary.objects.filter(user_id=user_id)
    if my_diaries:
        unread_num = DiaryVote.objects.filter(
            diary_id__in=my_diaries,
            unread=True
        ).count()
        count += unread_num

    topic_reply_unread_num = TopicReplyVote.objects.filter(
        topic_reply__user_id=user_id,
        unread=True
    ).count()
    count += topic_reply_unread_num

    tra_ids = list(Tractate.objects.filter(user_id=user_id, is_online=True).values_list('id', flat=True))
    tractate_vote_unread_num = TractateVote.objects.filter(
        tractate_id__in=tra_ids, is_read=False, is_online=True).count()
    count += tractate_vote_unread_num

    tra_reply_ids = list(Tractate.objects.filter(user_id=user_id, is_online=True).values_list('id', flat=True))
    tractate_reply_vote_unread_num = TractateReplyVote.objects.filter(
        tractate_id__in=tra_reply_ids, is_read=False, is_online=True
    ).count()
    count += tractate_reply_vote_unread_num

    if add_answer:
        answer_num = get_unread_answer_vote_num_by_user_id(user_id)
        count += answer_num
        answer_reply_num = get_unread_answer_reply_vote_num_by_user_id(user_id)
        count += answer_reply_num

    return count


def get_user_unread_vote_count(user_id):
    """
    通过user_id 获取当前用户的未读数
    :param user_id:
    :return:
    """
    if not user_id:
        return 0

    count = get_unread_vote_num_by_user_id(user_id, add_answer=True)
    return count


def get_answer_vote_info_by_ids(vote_ids):
    answer_vote_infos = get_answer_vote_infos_by_ids(vote_ids)
    return answer_vote_infos


def get_answer_vote_info_by_id(vote_id):
    """
    注意字典 key 数据类型
    :param vote_id: 回答点赞的id int 类型
    :return: {} 字典类型
    """
    vote_info = get_answer_vote_info_by_ids([vote_id])
    return vote_info and vote_info.get(str(vote_id), {}) or {}
