# -*- coding: UTF-8 -*-

from rpc.decorators import bind_context, bind
from talos.models.topic import TopicReply, ReplyHeadline, Problem
from hera.queries.talos.topicreply import TopicReplyDQ
from services.talos_service import topic_reply_update_reply_num_by_ids
from api.tool.user_tool import get_user_by_user_ids, filter_user_nick_name
from rpc.tool.dict_mixin import to_dict

uri_pre = 'hera/topicreply'


@bind_context(uri_pre + '/query')
def topicreply_query(ctx, options):
    dqobj = TopicReplyDQ()
    return dqobj.process(**options)


# comment - zhongchengyang 20170817
# @bind_context(uri_pre + '/list')
# def topicreply_datatable(ctx, req_data):
#     dtobj = TopicReplyDT(TopicReply)
#     return dtobj.process(req_data)


@bind_context(uri_pre + '/headupdate')
def head_update(ctx, items):
    info = [obj['key'] for obj in items]
    for obj in items:
        if obj['headline']:
            try:
                reply = TopicReply.objects.get(id=obj['key'])
                ReplyHeadline.objects.get_or_create(reply=reply)
            except TopicReply.DoesNotExist:
                continue
        else:
            ReplyHeadline.objects.filter(reply_id=obj['key']).delete()
    return info


@bind_context(uri_pre + '/listupdate')
def list_update(ctx, items):
    info = [obj['key'] for obj in items]
    online_ids = []
    not_online_ids = []
    for obj in items:
        topic_reply = TopicReply.objects.get(id=obj['key'])
        if topic_reply.is_online != obj['is_online']:
            # topic_reply.update_reply_num(is_online=obj['is_online'])
            if obj['is_online']:
                online_ids.append(topic_reply.id)
            else:
                not_online_ids.append(topic_reply.id)
        topic_reply.is_online = obj['is_online']
        topic_reply.save()
    topic_reply_update_reply_num_by_ids(ids=online_ids, is_online=True)
    topic_reply_update_reply_num_by_ids(ids=not_online_ids, is_online=False)
    return info



@bind(uri_pre + "/reply_list")
def reply_list(problem_id, size=10, commented_reply_id=0, last_id=0):
    """
    获取帖子评论，一级评论按照时间先后排序，二级评论跟着一级评论后
    :param problem_id: 帖子id
    :param size:
    :param commented_reply_id: 一级评论id
    :param last_id: 最后一条评论的id
    :return:
    """
    reply_infos = []
    # 第一次查询
    if not last_id:
        # 获取size条一级和次级评论
        reply_infos = TopicReply.get_replys(problem_id, last_id, size)
    else:
        # 获取当前一级评论剩余的次级评论 size 条
        sub_reply_info_list = list(TopicReply.objects.filter(
            problem_id=problem_id,
            commented_reply_id=commented_reply_id or last_id,
            is_online=True,
            id__gt=last_id,
        )[0: size])

        reply_infos.extend(sub_reply_info_list)

        # 如果总数小于size 往后查 size-len(reply_infos)条 一级和次级评论
        last_id = commented_reply_id or last_id
        if len(reply_infos) < size:
            _reply_infos = TopicReply.get_replys(problem_id, last_id, size - len(reply_infos))
            reply_infos.extend(_reply_infos)

    if not reply_infos:
        return []

    reply_list = []
    user_id_set = set()

    for reply in reply_infos:
        reply_info =  to_dict(
            reply,
            fields=['id', 'problem_id', 'user_id', 'commented_reply_id', 'content', 'reply_date']
        )
        reply_list.append(reply_info)
        user_id_set.add(reply_info['user_id'])

    user_info_dict = {user.id: filter_user_nick_name(user)for user in get_user_by_user_ids(list(user_id_set))}

    for item in reply_list:
        item['user_name'] = user_info_dict.get(item['user_id'], '')

    return reply_list


@bind(uri_pre + "/delete_reply")
def delete_reply(reply_id):
    """
    删除评论
    :param reply_id: 评论id
    :return:
    """
    try:
        reply = TopicReply.objects.get(id=reply_id)
    except TopicReply.DoesNotExist:
        return '评论不存在'

    reply.is_online = False
    reply.save()

    # 如果是一级评论 将commented_reply_id为当前评论id的评论下线，帖子评论数，减(1+下线评论数) 帖子医生评论数减去下线的医生评论数
    if not reply.commented_reply_id:
        doctor_reply_num = TopicReply.objects.filter(
            commented_reply_id=reply_id,
            doctor_id__isnull=False,
            is_online=True,
        ).count()

        effected_num = TopicReply.objects.filter(commented_reply_id=reply_id).update(is_online=False)

    # 如果是次级评论，则将replied_topic_id为当前评论id的评论下线， 帖子评论数，减(1+下线评论数) 帖子医生评论数减去下线的医生评论数
    else:
        sub_reply_id_list = TopicReply.get_sub_reply_ids(reply_id)

        if sub_reply_id_list:
            doctor_reply_num = TopicReply.objects.filter(
                id__in=sub_reply_id_list,
                doctor_id__isnull=False,
                is_online=True,
            ).count()

            effected_num = TopicReply.objects.filter(id__in=sub_reply_id_list).update(is_online=False)
        else:
            doctor_reply_num = 0
            effected_num = 0

    problem = Problem.objects.get(id=reply.problem_id)
    reply_num = problem.reply_num - effected_num - 1
    if reply_num < 0:
        reply_num = 0

    doctor_num = problem.doctor_num - doctor_reply_num
    if reply.doctor_id:
        doctor_num -= 1
    if doctor_num < 0:
        doctor_num = 0

    has_answer = TopicReply.objects.filter(
        problem=problem,
        diary__isnull=True,
        is_online=True,
        doctor_id__isnull=False
    ).exists()

    if not has_answer:
        problem.has_answer = has_answer

    problem.reply_num = reply_num
    problem.doctor_num = doctor_num

    problem.save()

    return "删除成功"
