# -*- coding: utf-8 -*-
from collections import defaultdict
from django.db.models import Q
from gm_types.doris import CARD_TYPE
from gm_types.mimas import (
    TRACTATE_PLATFORM,
    TRACTATE_REPLY_HIGHLIGHT
)
from gm_types.error import ERROR as CODES
from gm_dataquery.dict_mixin import to_dict

from gm_rpcd.all import RPCDFaultException

from qa.views.mark import get_author_id_by_business_id
from utils.rpc import gen, get_current_user
from utils.stat_log import SocialStatLogForUserAction

from talos.cache.base import reply_cache as reply_msg_cache
from talos.tools.replies_tool import ReplyTool
from talos.views.tractate.tractate import update_tractate_special_info

from talos.libs.datetime_utils import get_timestamp_or_none
from qa.utils.decorator import listing
from talos.rpc import bind_context, bind
from talos.services.tractate.tractate import TractateService
from talos.services.tractate.reply import TractateReplyService
from talos.services.tractate.vote import TractateReplyVoteService
from talos.services import get_user_from_context, UserService, UserConvertService
from talos.services.doctor import DoctorService
from talos.tools.tractate_reply_tool import reply_update_cache, get_reply_ids
from talos.tasks.tractate import reply_push, applet_replied_push, applet_reply_summary_push

uri_pre = 'mimas/tractate_reply/'


@bind_context(uri_pre + 'create', with_context=True)
def create_tractate_reply(ctx, tractate_id, content, replied_id=None, top_id=None, images=[]):
    """
    回复创建
    :param ctx:
    :param tractate_id:
    :param content:
    :param replied_id:
    :param top_id:
    :param images: 图片列表[{"image_url": "width": 0, "height": 0}]
    :return:
    """

    user = get_user_from_context(ctx)
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    tractate = TractateService.healthy(tractate_id)

    result = {
        "replied_user_id": "",
        "replied_user_portrait": "",
        "replied_user_name": ""
    }
    replied = None

    if not top_id and not replied_id:
        top_id = 0
    if replied_id and not top_id:
        top_id = replied_id

    if replied_id:
        replied_info = TractateReplyService.get_by_id(pk=replied_id)
        replied_user_info = UserConvertService.get_user_info_by_user_id(replied_info.user_id)
        result.update({
            "replied_user_id": replied_user_info.get("user_id", 0),
            "replied_user_portrait": replied_user_info.get("portrait", ""),
            "replied_user_name": replied_user_info.get("user_name", ""),
            "replied_user_info": replied_user_info,
        })

    reply = TractateReplyService.create(
        content=content, user_id=user.id,
        tractate_id=tractate_id, extra={
            "top_id": top_id,
            "replied_id": replied_id,
            "source_id": TRACTATE_PLATFORM.GM,
            "images": images,
        }
    )

    replied_user_id = replied_info.user_id if replied_id else tractate.user_id
    if user.id != replied_user_id:
        rt = ReplyTool(reply_msg_cache, replied_user_id)
        rt.receive_tractate_reply(reply.id)

    reply_push.delay(user_id=user.id, tractate_id=tractate_id, reply_id=reply.id, content=content)

    # 小程序推送
    applet_replied_push.delay(reply.id)
    applet_reply_summary_push.apply_async((reply.id,), countdown=86400)

    # 用户行为埋点 评论相关
    SocialStatLogForUserAction.stat_log_for_reply(
        content_type=SocialStatLogForUserAction.CONTENT_TYPE.user_post,
        content_id=tractate_id,
        user_id=user.id
    )

    #更新一级评论下的评论数
    if top_id:
        result.update({"top_id": int(top_id)})
        TractateReplyService.update_reply_count(top_reply_id=top_id)
    else:
        result.update({"replies": []})

    TractateService.incr_tractate_reply(tractate=tractate)

    reply_update_cache(user_id=user.id, tractate_id=tractate_id, reply_id=reply.id)

    result.update({
        'id': reply.id,
        'content': reply.content,
        'create_time': get_timestamp_or_none(reply.create_time),
        "replied_id": int(replied_id) if replied_id else '',
        "user_name": user.nickname,
        "user_id": user.id,
        "user_portrait": user.portrait,
        "is_vote": False,
        "vote_num": 0,
        "status": TRACTATE_REPLY_HIGHLIGHT.DARK,
        "reply_count": 0,
        "reply_user_info": UserConvertService.get_user_info_by_user_id(user.id),
    })
    return result


@bind_context(uri_pre + 'receive', with_context=True)
def get_replies_by_ids(ctx, replies_ids):

    user = get_user_from_context(ctx)
    if not user:
        return gen(CODES.LOGIN_REQUIRED)

    if not replies_ids:
        return {}

    replies_dict = TractateReplyService.get_replies_info(reply_ids=replies_ids)

    user_ids = []
    replied_ids = []
    tractates_ids = []
    for _, reply in replies_dict.items():
        user_ids.append(reply["user_id"])
        replied_ids.append(reply["replied_id"])
        tractates_ids.append(reply["tractate_id"])

    replied_dict = TractateReplyService.get_replies_info(reply_ids=replied_ids)
    users_dict = UserService.get_users_by_user_ids(user_ids)
    tractates_dict = TractateService.list_tractate_by_ids(tractates_ids)
    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(
        reply_ids=(replies_ids + replied_ids)
    )

    doctors_dict = {}
    doctors = DoctorService.get_doctor_from_user_ids(user_ids)
    for doctor in doctors:
        doctors_dict[doctor.user_id] = doctor

    result = {}
    for reply_id, reply in replies_dict.items():

        reply_user = users_dict.get(reply["user_id"], {})

        doctor = doctors_dict.get(reply["user_id"], {})
        doctor_info = {}
        if doctor:
            doctor_info = {
                "user_id": doctor.user_id,
                "doctor_id": doctor.id,
                "name": doctor.name,
            }

        replied = {}
        if reply["replied_id"]:
            item = replied_dict.get(reply["replied_id"], {})
            if item:
                replied = {
                    "id": reply["replied_id"],
                    "content": reply["content"],
                    "images": reply_images_dic.get(reply["replied_id"], []),
                }

        tractate = {}
        tractate_obj = tractates_dict.get(reply["tractate_id"])
        if tractate_obj:
            tractate = {
                "id": tractate_obj.id,
                "content": tractate_obj.content,
                "user_id": tractate_obj.user_id
            }

        info = {
            "id": reply["id"],

            "reply_date": reply["create_time"],
            "reply_content": reply["content"],
            "images": reply_images_dic.get(reply["id"], []),
            "tractate": tractate,

            "replied": replied,
            "reply_user": {
                "id": reply_user.id,
                "name": reply_user.nickname,
                "portrait": reply_user.portrait,
            },
            "author": {
                "id": user.id,
                "name": user.nickname,
                "portrait": user.portrait,
            },

            "doctor": doctor_info,
        }
        result[str(reply_id)] = info

    return result


@bind(uri_pre + 'top/list')
#@listing()
def list_top_reply(ctx, tractate_id, offset=0, count=10, sort_condition=None):
    """一级回复列表"""
    user = get_user_from_context(ctx)
    tractate = TractateService.healthy(tractate_id)

    replies = TractateReplyService.list_top_reply_by_tractate_id(tractate_id, offset, count)

    reply_ids , user_ids = [], []
    for reply in replies:
        reply_ids.append(reply.get("id"))
        user_ids.append(reply.get("user_id"))
    users = UserConvertService.get_user_info_by_user_ids(user_ids)

    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(reply_ids)

    for reply in replies:
        reply_user_info = users.get(reply.get('user_id'), {})
        if not reply_user_info:
            continue

        reply.update({
            "user_nickname": reply_user_info.get("user_name", ""),
            "user_portrait": reply_user_info.get("portrait", ""),
            "reply_user_info": reply_user_info,
            "images": reply_images_dic.get(reply.get("id"), []),
        })

    reply_num_total = tractate.reply_num

    return {
        'replies': replies,
        'reply_num_total': reply_num_total
    }


@bind(uri_pre + 'second_list')
@listing()
def gets_second_reply(reply_id, offset=0, count=10, user_id=None, sort_condition=None):
    """二级回复列表"""
    second_reply = TractateReplyService.get_second_reply_by_top_id(
        top_id=int(reply_id), offset=int(offset), count=int(count), sort_condition=sort_condition)

    user_ids, _reply_ids, replied_ids = set(), set(), set()
    for reply_item in second_reply:
        _user_id = reply_item.get("user_id", 0)
        _replied_id = reply_item.get("replied_id", 0)
        _id = reply_item.get("id", 0)

        if _user_id:
            user_ids.add(_user_id)

        if _replied_id:
            replied_ids.add(_replied_id)

        if _id:
            _reply_ids.add(_id)
    # 点赞状态
    vote_reply_ids = TractateReplyVoteService.model.objects.filter(
        user_id=user_id, reply_id__in=_reply_ids, is_online=True
    ).values_list("reply_id", flat=True)

    # 图片
    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(_reply_ids)

    # 评论数据信息
    replied_infos = TractateReplyService.get_replies_info(reply_ids=replied_ids)
    replyed_user_ids = set(v.get("user_id", 0) for v in replied_infos.values())

    all_user_ids = user_ids | replyed_user_ids
    users = UserConvertService.get_user_info_by_user_ids(all_user_ids)

    for reply in second_reply:
        reply_user_info = users.get(reply.get('user_id', 0), {})
        if not reply_user_info:
            continue

        replied_info = replied_infos.get(reply.get('replied_id'), {})
        replied_user_info = users.get(replied_info.get('user_id', 0), {})
        if not replied_user_info:
            continue

        reply.update({
            "images": reply_images_dic.get(reply.get("id"), []),
            "is_vote": True if reply.get('id') in vote_reply_ids else False,
            "user_name": reply_user_info.get("user_name", ""),
            "user_portrait": reply_user_info.get("portrait", ""),
            "replied_user_id": replied_user_info.get("user_id", 0),
            "replied_user_name": replied_user_info.get("user_name", ""),
            "replied_user_portrait": replied_user_info.get("portrait", ""),
            "reply_user_info": reply_user_info,
            "replied_user_info": replied_user_info,
        })

    return second_reply


@bind(uri_pre + 'top_list')
@listing()
def list_top_reply_by_tractate_ids(tractate_ids, offset=0, count=2, sort_condition=None):
    """多个帖子一级评论"""
    result, user_ids, reply_ids = {}, [], []
    for tractate_id in tractate_ids:
        _replies_list = TractateReplyService.list_top_reply_by_tractate_id(
            tractate_id=tractate_id, offset=offset, count=count, sort_condition=sort_condition
        )
        user_ids.extend([reply.get('user_id') for reply in _replies_list])
        reply_ids.extend([reply.get("id") for reply in _replies_list])
        result[str(tractate_id)] = _replies_list

    users = UserConvertService.get_user_info_by_user_ids(user_ids)
    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(reply_ids)

    for k, item in result.items():
        for reply in item:
            _user_info = users.get(reply.get("user_id", 0), {})
            if not _user_info:
                continue

            reply.update({
                "images": reply_images_dic.get(reply.get("id"), []),
                "user_nickname": _user_info.get("user_name", ""),
                "user_portrait": _user_info.get("portrait", ""),
                "reply_user_info": _user_info,
            })

    return result


@bind(uri_pre + 'top_list_include_second_comments')
@listing()
def list_top_reply_include_second_comments(
    tractate_ids, offset=0, count=2, user_id=None, sort_condition=None,
    top_id=None, reply_id=None
):
    """多个帖子一级评论 二级评论"""

    result = {}
    SECOND_COUNT, START_INDEX = 2, 0
    for tractate_id in tractate_ids:
        # 一级评论数据
        top_reply_infos = TractateReplyService.list_top_reply_by_tractate_id(
            tractate_id=int(tractate_id), offset=int(offset), count=int(count),
            sort_condition=sort_condition, top_id=top_id,
        )

        top_reply_user_ids, vote_reply_ids = set(), []
        second_user_ids, repied_ids = set(), []

        # 一级评论处理用户,点赞状态,二级评论及子评论逻辑
        for item in top_reply_infos:
            _user_id = item.get("user_id", 0)
            _id = item.get("id", 0)

            if _user_id:
                top_reply_user_ids.add(_user_id)
            if _id:
                vote_reply_ids.append(_id)

            second_reply_id = None
            if top_id == _id and top_id != reply_id:
                second_reply_id = reply_id

            # 二级评论
            second_reply = TractateReplyService.get_second_reply_by_top_id(
                top_id=_id,
                count=SECOND_COUNT,
                offset=START_INDEX,
                reply_id=second_reply_id
            )

            # 处理一级评论的子评论
            item['replies'] = second_reply

            for reply in second_reply:
                _reply_user_id = reply.get("user_id", 0)
                _replied_id = reply.get("replied_id", 0)
                _second_reply_id = reply.get("id", 0)

                if _reply_user_id:
                    second_user_ids.add(_reply_user_id)
                if _replied_id:
                    repied_ids.append(_replied_id)
                if _second_reply_id:
                    vote_reply_ids.append(_second_reply_id)

        # 处理二级评论、被评论用户信息
        replied_infos = TractateReplyService.get_replies_info(reply_ids=repied_ids)
        replyed_user_ids = set(v.get("user_id", 0) for v in replied_infos.values())

        # 取所有用户信息
        _all_user_ids = top_reply_user_ids | second_user_ids | replyed_user_ids
        all_user_infos = UserConvertService.get_user_info_by_user_ids(_all_user_ids)

        # 取所有已经被点赞的评论id
        voted_reply_ids = TractateReplyVoteService.get_vote_status(
            user_id=user_id, tractate_id=tractate_id, reply_ids=vote_reply_ids)

        # 图片
        all_reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(vote_reply_ids)

        # 评论信息处理
        for top_reply_info in top_reply_infos:

            top_reply_user_info = all_user_infos.get(top_reply_info.get("user_id", 0), {})
            if not top_reply_user_info:
                continue
            top_reply_info.update({
                "user_name": top_reply_user_info.get("user_name", ""),
                "user_portrait": top_reply_user_info.get("portrait", ""),
                "is_vote": bool(top_reply_info.get("id", 0) in voted_reply_ids),
                "top_reply_user_info": top_reply_user_info,
                "images": all_reply_images_dic.get(top_reply_info.get("id", 0), []),
            })

            # 二级评论信息处理
            for second_reply in top_reply_info.get('replies', []):
                second_reply_user_info = all_user_infos.get(second_reply.get("user_id", 0), {})

                if not second_reply_user_info:
                    continue

                replied_info = replied_infos.get(second_reply.get('replied_id'), {})
                replied_info_user_info = all_user_infos.get(replied_info.get("user_id", 0), {})
                if not replied_info_user_info:
                    continue

                second_reply.update({
                    "is_vote": bool(second_reply.get("id", 0) in voted_reply_ids),
                    "user_name": second_reply_user_info.get("user_name", ""),
                    "user_portrait": second_reply_user_info.get("portrait", ""),
                    "replied_user_id": replied_info_user_info.get("user_id", ""),
                    "replied_user_name": replied_info_user_info.get("user_name", ""),
                    "replied_user_portrait": replied_info_user_info.get("portrait", ""),
                    "second_reply_user_info": second_reply_user_info,
                    "replied_user_info": replied_info_user_info,
                    "images": all_reply_images_dic.get(second_reply.get("id", 0), []),
                })

        result[str(tractate_id)] = top_reply_infos

    return result


@bind(uri_pre + 'reply_popup')
@listing()
def get_reply_in_popup(tractate_id, offset=0, count=5, user_id=None, sort_condition=None):
    """评论弹窗~获取评论(一级和二级)"""
    SECOND_COUNT, START_INDEX = 2, 0
    TractateService.healthy(tractate_id)

    # 一级评论数据
    top_reply_infos = TractateReplyService.list_top_reply_by_tractate_id(
        tractate_id=int(tractate_id), offset=int(offset), count=int(count), sort_condition=sort_condition
    )

    top_reply_user_ids, vote_reply_ids = set(), []
    second_user_ids, repied_ids = set(), []

    # 一级评论处理用户,点赞状态,二级评论及子评论逻辑
    for item in top_reply_infos:
        _user_id = item.get("user_id", 0)
        _id = item.get("id", 0)

        if _user_id:
            top_reply_user_ids.add(_user_id)
        if _id:
            vote_reply_ids.append(_id)

        # 二级评论
        second_reply = TractateReplyService.get_second_reply_by_top_id(
            top_id=_id,
            count=SECOND_COUNT,
            offset=START_INDEX,
            sort_condition=sort_condition
        )

        # 处理一级评论的子评论
        item['replies'] = second_reply

        for reply in second_reply:
            _reply_user_id = reply.get("user_id", 0)
            _replied_id = reply.get("replied_id", 0)
            _second_reply_id = reply.get("id", 0)

            if _reply_user_id:
                second_user_ids.add(_reply_user_id)
            if _replied_id:
                repied_ids.append(_replied_id)
            if _second_reply_id:
                vote_reply_ids.append(_second_reply_id)

    # 处理二级评论、被评论用户信息
    replied_infos = TractateReplyService.get_replies_info(reply_ids=repied_ids)
    replyed_user_ids = set(v.get("user_id", 0) for v in replied_infos.values())

    # 取所有用户信息
    _all_user_ids = top_reply_user_ids | second_user_ids | replyed_user_ids
    all_user_infos = UserConvertService.get_user_info_by_user_ids(_all_user_ids)

    # 取所有已经被点赞的评论id
    voted_reply_ids = TractateReplyVoteService.get_vote_status(
        user_id=user_id, tractate_id=tractate_id, reply_ids=vote_reply_ids)

    # 图片
    all_reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(vote_reply_ids)

    #评论信息处理
    for top_reply_info in top_reply_infos:

        top_reply_user_info = all_user_infos.get(top_reply_info.get("user_id", 0), {})
        if not top_reply_user_info:
            continue
        top_reply_info.update({
            "user_name": top_reply_user_info.get("user_name", ""),
            "user_portrait": top_reply_user_info.get("portrait", ""),
            "is_vote": bool(top_reply_info.get("id", 0) in voted_reply_ids),
            "top_reply_user_info": top_reply_user_info,
            "images": all_reply_images_dic.get(top_reply_info.get("id", 0), []),
        })

        # 二级评论信息处理
        for second_reply in top_reply_info.get('replies', []):
            second_reply_user_info = all_user_infos.get(second_reply.get("user_id", 0), {})

            if not second_reply_user_info:
                continue

            replied_info = replied_infos.get(second_reply.get('replied_id'), {})
            replied_info_user_info = all_user_infos.get(replied_info.get("user_id", 0), {})
            if not replied_info_user_info:
                continue

            second_reply.update({
                "is_vote": bool(second_reply.get("id", 0) in voted_reply_ids),
                "user_name": second_reply_user_info.get("user_name", ""),
                "user_portrait": second_reply_user_info.get("portrait", ""),
                "replied_user_id": replied_info_user_info.get("user_id", ""),
                "replied_user_name": replied_info_user_info.get("user_name", ""),
                "replied_user_portrait": replied_info_user_info.get("portrait", ""),
                "second_reply_user_info": second_reply_user_info,
                "replied_user_info": replied_info_user_info,
                "images": all_reply_images_dic.get(second_reply.get("id", 0), []),
            })

    return top_reply_infos


@bind(uri_pre + 'light_reply')
def get_light_reply(tractate_id, user_id=None, target_reply_id=None):
    """获取高亮评论"""
    SECOND_COUNT, START_INDEX = 2, 0
    more_highlight = True

    if not target_reply_id:
        return gen(CODES.PARAMS_INCOMPLETE)

    top_info = TractateReplyService.get_highlight_reply(target_reply_id=target_reply_id)

    if not top_info:
        return []

    user_ids, replied_ids, vote_reply_ids = set(), set(), set()

    user_ids.add(top_info.get('user_id'))
    vote_reply_ids.add(top_info.get("id"))

    second_replies = TractateReplyService.get_second_reply_by_top_id(
        top_id=top_info.get('id'), count=SECOND_COUNT, target_reply_id=target_reply_id)

    for reply in second_replies:
        _reply_user_id = reply.get("user_id", 0)
        _replied_id = reply.get("replied_id", 0)
        _second_reply_id = reply.get("id", 0)

        if _reply_user_id:
            user_ids.add(_reply_user_id)

        if _replied_id:
            replied_ids.add(_replied_id)

        if _second_reply_id:
            vote_reply_ids.add(_second_reply_id)

    replied_infos = TractateReplyService.get_replies_info(reply_ids=replied_ids)
    for key, value in replied_infos.items():
        user_ids.add(value.get('user_id', 0))

    #获取用户是否点过赞
    voted_reply_ids = TractateReplyVoteService.get_vote_status(
        user_id=user_id, tractate_id=tractate_id, reply_ids=vote_reply_ids
    )

    # 图片
    all_reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(vote_reply_ids)

    # 所有用户
    all_user = UserConvertService.get_user_info_by_user_ids(user_ids)

    for second_reply in second_replies:
        second_reply_user_info = all_user.get(second_reply.get("user_id", 0), {})

        if not second_reply_user_info:
            continue

        replied_info = replied_infos.get(second_reply.get('replied_id'), {})
        replied_info_user_info = all_user.get(replied_info.get("user_id", 0), {})
        if not replied_info_user_info:
            continue

        if not top_info['status'] and second_reply['status'] == TRACTATE_REPLY_HIGHLIGHT.LIGHT:
            more_highlight = False

        second_reply.update({
            "is_vote": True if second_reply.get('id') in voted_reply_ids else False,
            "user_name": second_reply_user_info.get("user_name", ""),
            "user_portrait": second_reply_user_info.get("portrait", ""),
            "replied_user_id": replied_info_user_info.get("user_id", ""),
            "replied_user_name": replied_info_user_info.get("user_name", ""),
            "replied_user_portrait": replied_info_user_info.get("portrait", ""),
            "second_reply_user_info": second_reply_user_info,
            "replied_user_info": replied_info_user_info,
            "images": all_reply_images_dic.get(second_reply.get("id", 0), []),
        })

    top_user_info = all_user.get(top_info.get("user_id", 0), {})
    top_info.update({
        "replies": second_replies,
        "user_id": top_user_info.get("user_id", 0),
        "user_name": top_user_info.get("user_name", ""),
        "user_portrait": top_user_info.get("portrait", ""),
        "is_vote": True if top_info.get('id') in voted_reply_ids else False,
        "top_reply_user_info": top_user_info,
        "images": all_reply_images_dic.get(top_info.get("id", 0), []),
    })

    if not top_info['status'] and more_highlight:
        top_info['status'] = TRACTATE_REPLY_HIGHLIGHT.MORE_LIGHT

    return [top_info]


@bind(uri_pre + 'get_info')
def get_reply_by_id(reply_id):
    if not reply_id:
        return gen(CODES.PARAMS_INCOMPLETE)

    reply = TractateReplyService.get_by_id(pk=int(reply_id))

    reply = to_dict(reply)
    user_info = UserConvertService.get_user_info_by_user_id(reply.get('user_id'))
    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids([reply.id])

    reply.update({
        "user_nickname": user_info.get("user_name", ""),
        "user_portrait": user_info.get("portrait", ""),
        "reply_user_info": user_info,
        "images": reply_images_dic.get(reply.id, []),
    })

    return reply


@bind(uri_pre + 'get_by_tractate')
#@listing()
def get_reply_by_tractate(user_id, offset=0, count=10, tractate_from='', use_new_query=False):
    """
    :param user_id:
    :param offset:
    :param count:
    :param tractate_from:   7.12.0 帖子入口
    :param use_new_query:    7.12.0  版本兼容
    :return:
    """
    if not user_id:
        return gen(CODES.LOGIN_REQUIRED)

    data = get_reply_ids(user_id=user_id)

    dic_reply = data.get('dic_reply')
    reply_infos = TractateReplyService.get_replies_info(reply_ids=data.get('reply_ids', []))
    reply_images_dic = TractateReplyService.get_reply_images_by_reply_ids(reply_ids=data.get('reply_ids', []))

    _tractate_ids = TractateService.get_tractate_ids_by_query_and_order(
        query=Q(id__in=data.get('tractate_ids', [])),
        order_by=["-id"],
        offset=offset,
        size=count,
        tractate_from=tractate_from,
        use_new_query=use_new_query
    )
    tractate_list = []

    if _tractate_ids:
        tractates_info_dic = TractateService.get_tractate_infos_by_ids(
            tractate_ids=_tractate_ids,
            need_special_info=True,
            tractate_from=tractate_from,
            use_new_query=use_new_query,
        )
        # 增加浏览量
        TractateService.tractate_view_increase_num(tractates_info_dic.get("valid_tractate_ids", []))
        tractate_list = update_tractate_special_info(tractates_info_dic.get("tractate_list", []), _tractate_ids, user_id)

    for tractate in tractate_list:
        _reply_id = dic_reply.get(tractate.get('tractate_id'))
        if _reply_id:

            _reply_data = reply_infos.get(_reply_id)
            if not _reply_data:
                continue

            _reply_data.update({
                "images": reply_images_dic.get(_reply_id, []),
            })
            tractate['reply'] = _reply_data

    return tractate_list


@bind_context(uri_pre + 'received_aggregation', with_context=True)
def tractate_reply_reseived_aggregation(ctx):

    result = {
        "count": 0,
        "last_user_info": {},
        "create_time": 0,
    }
    user = get_user_from_context(ctx)
    if not user:
        return result

    info = TractateReplyService.get_tractate_reply_count_info(user.id)

    count = info["count"]
    last_user_id = info["last_user_id"]
    created_time = info["create_time"]
    if not count or not last_user_id:
        return result

    # get_user_from_context
    # last_user_info = UserConvertService.get_user_info_by_user_id(last_user_id)
    result["count"] = count
    result["create_time"] = get_timestamp_or_none(created_time)

    _user_info = {
        "nickname": user.nickname,
        "portrait": user.portrait,
    }

    result["last_user_info"] = _user_info

    return result


@bind(uri_pre + 'read')
def tractate_reply_read():

    user = get_current_user()
    if not user:
        return

    TractateReplyService.read_all(user.id)


@bind('mimas/mark/tractate_replies')
def get_mark_tractate_replies(tractate_ids, sort_type=None, first_reply_count=2, second_reply_count=1):
    """
    打卡贴的评论 2条一级 + 1条二级
    :param tractate_ids:
    :param sort_type:
    :param first_reply_count:
    :param second_reply_count:
    :return:
    """

    result = {
        "replies": {},
    }
    if not tractate_ids:
        return result

    user = get_current_user()
    _user_id = user and user.id or None
    replies_ids = set()
    tractate_ids = list(map(int, tractate_ids))
    # 一级评论
    first_replies = TractateReplyService.top_replies_by_tractate_ids(
        tractate_ids, sort_type=sort_type
    )
    first_reply_ids = first_replies.get('first_reply_ids', [])
    user_ids = first_replies.get('first_reply_user_ids', set())
    first_replies = first_replies.get('first_replies', {})
    reply_voted_ids = TractateReplyVoteService.get_vote_status(
        user_id=_user_id, tractate_id=None, reply_ids=first_reply_ids
    )
    replies_ids.update(first_reply_ids)

    # 二级评论
    second_reply_dict = TractateReplyService.get_second_replies_by_first_ids(
        first_reply_ids, count=second_reply_count,
    )
    user_ids.update(second_reply_dict.get('second_reply_user_ids', set()))
    user_dict = TractateService.get_user_info_by_user_ids(user_ids)
    second_replies = second_reply_dict.get('second_reply', {})
    replies_ids.update(second_reply_dict.get('second_reply_ids', []))
    # 二级评论的评论数
    second_reply_count_dic = TractateReplyService.get_second_replies_count(second_reply_dict.get('second_reply_ids', []))

    reply_images_dict = TractateReplyService.get_reply_images_by_reply_ids(reply_ids=replies_ids)

    # 一二级评论拼接
    reply_dict = defaultdict(list)
    for (tractate_id, reply_id), reply in first_replies.items():
        first_reply_id = reply.get('reply_id')
        author_id = reply.get('user_id', 0)
        if not first_reply_id:
            continue
        reply['author'] = user_dict.get(author_id, {})
        reply['is_vote'] = first_reply_id in reply_voted_ids
        reply['images'] = reply_images_dict.get(first_reply_id, [])
        second_reply = second_replies.get(first_reply_id, {})
        if second_reply:
            second_reply['author'] = user_dict.get(second_reply.get('user_id', 0), {})
            second_reply['images'] = reply_images_dict.get(second_reply.get('id'), [])
            second_reply['reply_count'] = second_reply_count_dic.get(second_reply.get('id'), 0)
        reply['comments'] = [second_reply]

        reply_dict[str(tractate_id)].append(reply)
    result['replies'] = reply_dict

    return result