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

import datetime

from urllib.parse import urljoin
from django.db import transaction
from django.db.models import F
from django.conf import settings

from gm_dataquery.dict_mixin import to_dict
from gm_types.mimas import (
    TRACTATE_STATUS,
    TRACTATE_PLATFORM,
    TRACTATE_CONTENT_LEVEL,
    TRACTATE_DATA_TYPE
)
from gm_rpcd.all import (
    RPCDFaultException,
    bind,
)
from gm_types.push import AUTOMATED_PUSH, PUSH_INFO_TYPE
from gm_upload.utils.image_utils import Picture
from utils.rpc import gen
from utils.protocol import gm_protocol

from talos.libs.image_utils import fetch_picture_and_save_to_qiniu_v2
from talos.models.soft_article import (
    SoftArticle,
    SoftArticleReply,
    SoftArticleCheck,
    SoftArticleVote,
    SoftArticleReplyVote,
    SoftArticleFavor,
    SoftArticleVideo,
    SoftArticleRelation,
    SoftArticleImages,
    SoftArticleExtra,

)
from talos.rpc import (
    bind_context,
)
from talos.services import UserService, get_user_from_context, UserConvertService
from talos.services.soft_article.reply import SoftArticleReplyService
from talos.services.soft_article.soft_article import SoftArticleService
from talos.models.soft_article.check import SoftArticleCheck
from talos.tasks.tractate import doctor_reply_push

uri_pre = 'mimas/backstage_soft_article'


@bind_context(uri_pre + '/create')
def create_soft_article(ctx, soft_article_info):

    content = soft_article_info.get("content", "")
    tag_ids = soft_article_info.get("tag_ids", [])
    title = soft_article_info.get("title", "")
    user_id = soft_article_info.get("user_id")
    service_id = soft_article_info.get("service_id")
    diary_id = soft_article_info.get("diary_id")
    list_img = soft_article_info.get("list_img")
    video_url = soft_article_info.get("video_url")

    soft_article = SoftArticleService.create(user_id=user_id, content=content, title=title, extra={
        "img_list": list_img, "videos": video_url, "tag_ids": tag_ids, "diary_id": diary_id, "service_id": service_id,
    })

    return soft_article


@bind(uri_pre + '/check')
def check_soft_article(soft_article_id, is_online, is_pass, reason="", content_level=''):
    s_check = SoftArticleCheck.objects.filter(softarticle_id=int(soft_article_id)).first()
    if not s_check:
        return {"status": 0}

    s_check.is_online = int(is_online)
    s_check.status = is_pass
    s_check.check_content = reason
    s_check.online_time = datetime.datetime.now()
    s_check.content_level = content_level
    s_check.save()

    article = SoftArticle.objects.filter(id=int(soft_article_id)).first()
    article.hera_is_online = True if article.is_online and int(is_online) else False
    article.status = is_pass
    article.save()

    return {"status": 1}


@bind(uri_pre + '/content_level')
def article_content_level(article_id, content_level):
    article = SoftArticle.objects.filter(id=article_id).first()
    if not article:
        return {"status": 0}

    article.content_level = int(float(content_level))
    article.save()

    return {"status": 1}


@bind(uri_pre + '/get_content_level')
def get_content_level(article_id):
    article = SoftArticle.objects.filter(id=article_id).first()

    return article.content_level


@bind('mimas/article_fake_reply/create')
def fake_reply_create(article_id, data=None):
    """
    帖子评论灌水
    :param article_id:
    :param data:
    :return:
    """
    result = {
        'error': 0,
        'message': '创建成功',
        'data': ''
    }
    if not all([article_id, data]):
        result['message'] = '参数不完整'
        return result

    article = SoftArticle.objects.get(id=article_id)

    user_ids = [item['user_id'] for item in data]
    user_ids = set(filter(None, user_ids))
    user_dic = UserService.get_users_by_user_ids(user_ids)

    reply_list = []
    for reply_data in data:
        obj = {
            'softarticle_id': article.id,
            'merchant_id': article.merchant_id,
            'doctor_id': article.doctor_id,
            'user_id': reply_data['user_id'],
            'content': reply_data['content'],
            'is_fake': True,
            'source_id': TRACTATE_PLATFORM.HERA,
            'top_id': 0,
            'replied_id': 0,
        }

        user = user_dic.get(int(reply_data['user_id']))
        nickname = user.nickname if user else '更美用户'

        push_dic = format_article_push_content(user_id=reply_data['user_id'], article=article, nickname=nickname)
        push_dic.update({
            'reply_obj': obj,
        })

        reply_list.append(push_dic)

    return {'reply_list': reply_list}


def format_article_push_content(user_id, article, nickname):

    push_url = gm_protocol.get_tractate_detail(tractate_id=article.id, data_type=TRACTATE_DATA_TYPE.DOCTOR)
    push_type = AUTOMATED_PUSH.TRACTATE_GET_REPLY
    extra = {
        'type': PUSH_INFO_TYPE.GM_PROTOCOL,
        'msgType': 4,
        'pushUrl': push_url,
        'push_url': push_url,
    }

    author_id = UserService.get_user_id_by_doctor_id(article.doctor_id)
    push_msg = "{user}回复了#你的帖子#{content}".format(
        user=nickname,
        content=article.content[:6])

    _item = {
        'author_id': author_id,
        'reply_user_id': user_id,
        'nickname': nickname,
        'push_msg': push_msg,
        'push_type': push_type,
        'push_url': push_url,
        'extra': extra,
        '_type': TRACTATE_DATA_TYPE.DOCTOR
    }

    return _item


@bind("mimas/hera_article/reply_list")
def reply_list(softarticle_id, size=10, top_id=0, last_id=0):
    """
    获取医生帖评论，一级评论按照时间先后排序，二级评论跟着一级评论后
    :param softarticle_id: 帖子id
    :param size:
    :param first_reply: 一级评论id
    :param last_id: 最后一条评论的id
    :return:
    """
    reply_infos = []
    # 第一次查询
    if not last_id:
        # 获取size条一级和次级评论
        reply_infos = SoftArticleReplyService.get_replys(softarticle_id, last_id, size)
    else:
        # 获取当前一级评论剩余的次级评论 size 条
        sub_reply_info_list = list(SoftArticleReply.objects.filter(
            softarticle_id=softarticle_id,
            top_id=top_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 = top_id or last_id
        if len(reply_infos) < size:
            _reply_infos = SoftArticleReplyService.get_replys(softarticle_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', 'softarticle_id', 'user_id', 'top_id', 'content', 'create_time'])
        reply_list.append(reply_info)
        user_id_set.add(reply_info['user_id'])

    all_user_infos = UserConvertService.get_user_info_by_user_ids(list(user_id_set))

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

    return reply_list


@bind("mimas/hera_article/create_reply")
def create_reply(content, user_id, softarticle_id, reply_id=0):
    """hera后台创建评论和回复"""
    article = SoftArticleService.healthy(softarticle_id)

    top_id = 0
    if reply_id:
        replied_info = SoftArticleReplyService.healthy(reply_id)
        top_id = replied_info.top_id or replied_info.id

    reply = SoftArticleReplyService.create(
        content=content,
        user_id=user_id,
        merchant_id=article.merchant_id,
        soft_article_id=softarticle_id,
        extra={
            "top_id": top_id,
            "replied_id": reply_id,
            "source_id": TRACTATE_PLATFORM.HERA,
            "is_fake": True
        },
    )

    doctor_reply_push.delay(soft_article_id=softarticle_id, reply_id=reply.id)

    # 更新一级评论下的评论数
    if reply_id:
        SoftArticleReplyService.update_reply_count(top_reply_id=top_id)

    SoftArticleService.incr_article_reply(soft_article_id=softarticle_id)
    return "回复成功" if reply_id else "评论成功"


@bind("mimas/hera_article/delete_reply")
def delete_reply(reply_id):
    """hera后台创建评论和回复"""
    reply_info = SoftArticleReplyService.healthy(reply_id)

    reply_info.is_online = False
    reply_info.save()
    reply_id = reply_info.id
    # 如果是一级评论 则将top_id为当前评论id的评论下线
    top_id = reply_info.top_id
    if not top_id:
        effected_num = SoftArticleReplyService.offline_by_top_id(reply_id)

    # 如果是次级评论，则将replied_id为当前评论id的评论下线 以及replied_id为下线评论id的评论下线
    else:
        effected_num = SoftArticleReplyService.offline_by_replied_id(reply_id)

    # 更新一级评论下的评论数
    top_reply_count = int(SoftArticleReplyService.top_reply_count(top_id or reply_id))

    new_reply_count = top_reply_count - effected_num
    if top_id:
        new_reply_count -= 1
    if new_reply_count < 0:
        new_reply_count = 0
    SoftArticleReplyService.set_reply_count(top_id or reply_id, new_reply_count)

    # 更新帖子评论
    softarticle_id = reply_info.softarticle_id
    reply_amount = SoftArticleService.get_article_reply(softarticle_id)
    new_reply_amount = reply_amount - effected_num - 1
    if new_reply_amount < 0:
        new_reply_amount = 0
    SoftArticleService.update_article_reply(softarticle_id, new_reply_amount)

    return "删除成功"
