# -*- coding: UTF-8 -*-
from django.conf import settings
from django.db.models import Q
from gm_types.gaia import PROBLEM_FLAG_CHOICES, TOPIC_TYPE
from gm_types.error import ERROR as CODES

from talos.models.topic import Problem, TopicReply, TopicScore
from talos.libs.datetime_utils import get_timestamp_or_none
from talos.services import UserService
from utils.rpc import gen, logging_exception


def need_convert(cnt):
    """
    格式化要求为日记本，日记贴, 日记贴，日记本，日记贴循环
    将判断是否需要转换的逻辑统一摆放，以防以后要改变循环顺序
    """
    return True


def get_topic_by_id(topic_id):
    try:
        problem = Problem.objects.get(id=topic_id)
        return problem
    except Problem.DoesNotExist:
        return None


def get_topic_reply_by_id(reply_id):
    """
    给定id, 获取对应的topic_reply
    @param reply_id:
    @return:
    """
    topic_replies = list(TopicReply.objects.filter(id=reply_id)[:1])
    if topic_replies:
        return topic_replies[0]
    else:
        return None


def update_topic_score(user, topic, score):
    topic_score, created = TopicScore.objects.get_or_create(topic=topic, user=user)
    topic_score.score = score
    topic_score.save()
    return topic_score.id


def get_replies_info(user, replies, start_num=0, count=10, is_recommand=False):
    result = []
    for reply in replies[start_num:start_num + count]:
        replies_data = reply.get_reply_detail(user.id)
        reply_info = replies_data['reply']
        if reply.replyheadline_set.count() == 0:
            replies_data['reply']['is_recommand'] = False
        else:
            replies_data['reply']['is_recommand'] = True

        replies_data['reply']['is_elite'] = (1 if reply_info['favor_amount'] >= settings.ELITE_LIKE_NUM else 0)
        comments = reply.comments.filter(is_online=True)
        replies_data[u'comments'] = [comment.comment_data() for comment in comments]
        result.append(replies_data)
    return result


def get_replies_list_info(user, query, start_num=0, count=10):
    """
    NOTE:
        首先获取热门评论数目
        如果不够，则继续获取最新评论
        获取 日记本 帖子 评论列表信息
    :param user:
    :param start_num:
    :param count:
    :return:
    """
    recommand_reply = (Q(replyheadline__is_online=True) | Q(like_num__gte=settings.ELITE_LIKE_NUM))
    recommand_reply &= query
    replies = TopicReply.objects.filter(recommand_reply)
    hot_count = replies.count()

    result = []
    if hot_count > start_num:
        replies = replies.order_by('-replyheadline__is_online', '-like_num', '-reply_date')
        result = get_replies_info(user, replies,
                                  start_num=start_num,
                                  count=count)

    if len(result) < count:
        if start_num < hot_count:
            start_num = 0
        else:
            start_num = start_num - len(result)

        count -= len(result)
        last_query = Q(like_num__lt=settings.ELITE_LIKE_NUM)
        last_query &= query
        last_replies = TopicReply.objects.filter(last_query).order_by('-id').exclude(recommand_reply)
        last_result = get_replies_info(user, last_replies,
                                       start_num=start_num,
                                       count=count)
        result.extend(last_result)

    return result


def get_feed_topic_info(topic_ids, user=None):
    if not topic_ids:
        return []

    result = []
    topic_ids = map(lambda x: int(x), topic_ids)
    q = Q(id__in=topic_ids) & Q(is_online=True) & Q(flag=PROBLEM_FLAG_CHOICES.NORMAL)
    topics = Problem.objects.filter(q)
    topics = sorted(topics, key=lambda x: topic_ids.index(x.pk))
    for topic in topics:
        try:
            if not (not topic.diary or
                        (topic.diary and topic.diary.is_online is True)):
                continue
            topic_data = topic.get_topic_info(user)
            result.append(topic_data)

        except Problem.DoesNotExist:
            pass

    return result


def reply_detail_diary(user, reply_id, start_num=0, count=10):
    try:
        reply = TopicReply.objects.get(pk=reply_id)
    except TopicReply.DoesNotExist:
        return gen(CODES.TOPIC_NOT_FOUND)
    topic = reply.problem

    user_id = topic.user.id
    user = UserService.get_user_by_user_id(user_id=user_id)
    user_portrait = user.portrait
    user_nickname = user.nickname
    city = user.city_name

    result = {
        'comments': [],
        'topic_id': topic.id,
        'title': topic.diary.title,

        'comment_count': topic.topicreply_set.count(),
        'reply_id': reply.id,
        'is_private': False if not user else user.id == user_id,
        'doctor_id': '',
        'doctor_portrait': '',
        'doctor_name': '',
        'hospital_name': '',
        'is_recommend_doctor': False,
        'recommend_doctor_title': '',
        'favored': False,
        'favor_amount': topic.vote_amount,
        'content': topic.answer,
        'images': [i.get_image_data() for i in topic.images.all()],
        'user_id': user_id,
        'user_nickname': user_nickname,
        'user_portrait': user_portrait,
        'is_star_user': False,
        'reply_date': get_timestamp_or_none(topic.created_time),
        'city': city,
        'is_topic_append': True,
    }

    doctor_reply_sql = """
        (case when api_topicreply.doctor_id !='' then 1 else 0 end)
    """
    comments = topic.topicreply_set.extra(
        select={'doctor_reply': doctor_reply_sql})
    comments = comments.extra(order_by=['-doctor_reply', 'id'])
    comments = comments[start_num: start_num + count]
    for r in comments:
        result['comments'].append(r.comment_data())

    return result



def filter_user_by_topic_to_push(start_time):
    '''
    获取近30天内有更新日记操作的用户，to push 
    :param start_time: 
    :return: 
    '''
    q = Q(topic_type=TOPIC_TYPE.SHARE) & Q(is_online=True) & Q(flag=PROBLEM_FLAG_CHOICES.NORMAL)
    topics = Problem.objects.filter(q & Q(created_time__gt=start_time)).order_by('-created_time')

    result = []
    uid_set = set()
    for topic in topics:
        try:
            if not topic.user_id in uid_set:
                d = {
                    'uid': topic.user_id,
                    'diary_id': topic.diary.id,
                    'created_time': topic.created_time
                }
                result.append(d)
                uid_set.add(topic.user_id)
        except:
            logging_exception()
            continue

    return result