#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 问答创建
import datetime
import json

from gm_types.antispam import DocType
from gm_types.doctor import DOCTOR_TITLE_TYPE
from gm_types.error import ERROR
from gm_types.gaia import (
    DOCTOR_PROCESS_STATUS,
    CONST_STRINGS as const_strings,
)
from gm_types.mimas import (
    CONTENT_CLASS,
    MEDIA_IMAGE_URL_SOURCE,
    QA_CONTENT_TYPE,
    VIDEO_SOURCE_TYPE,
    COMMUNITY_CONTENT_TYPE)

from communal.tasks import create_fake_task
from live.tasks import get_qiniu_persistent_ids
from qa.cache.manager import AnswerSortCacheManager
from qa.libs import (
    format_qa_content_v2,
    get_media_extra_info,
    refine_qa_content_data,
    get_head_image_info,
)
from qa.models.answer import (
    AnswerTag,
    Question,
    AnswerTagV3,
    AnswerAttrTagV3,
)
from qa.serializers import (
    AnswerSerializer,
)
from qa.tasks import (
    check_spam,
    fake_vote_to_answer,
    push_to_question_provider,
)
from qa.utils.statistic import get_async_args_v2

from talos.logger import irrigation_logger
from talos.portal import (
    get_doctor_by_user_id,
)
from talos.models.doctor import DoctorMessageList
from utils.common import get_data_from_rich_text
from utils.push import push_time_range_limit
from utils.rpc import (
    gen,
    logging_exception,
)
from utils.tasks import common_push


class AnswerCreateMethod(object):

    @staticmethod
    def _create_answer(user, create_data):
        """
        创建回答
        :param user:
        :param create_data: {question_id:xx, content: ", images: [], platform:None or 99, tag_ids: [], "tag_v3_ids": []}
        :return:
        """
        result = {
            "answer": {},
            "doctor": None,
        }
        question_id = create_data.get("question_id", 0)
        content = create_data.get("content", "")
        _images = get_media_extra_info(create_data.get("images", []))
        head_images = get_head_image_info(create_data.get("head_images", []))
        tag_ids = create_data.get("tag_ids", [])
        tags = [{'tag': tag} for tag in tag_ids]

        _data = {
            "question": question_id,
            "user": user.id,
            "content": content,
            "tags": tags,
            'level': create_data.get("level", CONTENT_CLASS.UNAUDITED)
        }

        platform = create_data.get("platform", None)
        if platform:
            rich_text_dic = refine_qa_content_data(content)
            rich_images_list = get_media_extra_info(rich_text_dic.get("images_list", []))
            for item in rich_images_list:
                item.update({
                    "image_url_source": MEDIA_IMAGE_URL_SOURCE.RICH_TEXT,
                })
            _images.extend(rich_images_list)
            _data.update(format_qa_content_v2(platform, content))
        _images = head_images + _images
        _data.update({
            "images": _images,
            "platform": platform,
        })

        try:
            doctor = get_doctor_by_user_id(user.id)
        except IndexError:
            doctor = None

        if doctor:
            _data.update({
                "doctor_id": doctor.id,
                "doctor_title": doctor.title or DOCTOR_TITLE_TYPE.EMPTY,
            })
            result["doctor"] = doctor

        serializer = AnswerSerializer(data=_data)

        if not serializer.is_valid(raise_exception=False):
            gen(ERROR.CONTENT_CREATE_ERROR)

        serializer.save()
        answer_data = serializer.data

        answer_tag_v3s = [AnswerTagV3(
            answer_id=answer_data["id"],
            tag_v3_id=tag_v3_id
        ) for tag_v3_id in create_data.get("tag_v3_ids", [])]
        if answer_tag_v3s:
            AnswerTagV3.objects.bulk_create(answer_tag_v3s)

        if create_data.get("v3_attr_tag_ids", []):
            AnswerAttrTagV3.objects.bulk_create([
                AnswerAttrTagV3(
                    answer_id=answer_data["id"],
                    attr_tag_id=attr_tag_id
                ) for attr_tag_id in create_data.get("v3_attr_tag_ids", [])])

        result["answer"] = answer_data

        return result

    @staticmethod
    def various_logic_after_answer_create(answer_data, doctor):
        """
        回答创建后触发的逻辑
        :param answer_data:
        :param doctor:
        :param user:
        :return:
        """
        question_id = answer_data.get("question", 0)
        answer_id = answer_data.get("id", 0)

        if doctor:
            DoctorMessageList.objects.filter(
                question_id=question_id, doctor_id=doctor.id
            ).update(process_status=DOCTOR_PROCESS_STATUS.processed)

        if answer_data.get("content_type", "") == QA_CONTENT_TYPE.VIDEO:
            _, video_list = get_data_from_rich_text(
                answer_data.get("content", ""),
                u'//video[not(@name="new_video")]/@src'
            )
            if video_list:
                get_qiniu_persistent_ids.delay(
                    source_id=answer_id,
                    video_type=VIDEO_SOURCE_TYPE.ANSWER,
                    url_list=video_list
                )

    @staticmethod
    def trigger_tasks_after_answer_reply_create(answer_data, user, **kwargs):
        """
        回答创建完毕，触发的各种异步任务
        :param answer_data:
        :param user:
        :param tag_ids:
        :return:
        """
        question_id = answer_data.get("question", 0)
        answer_id = answer_data.get("id", 0)

        tag_ids = kwargs.get("tag_ids", [])
        tag_v3_ids = kwargs.get("tag_v3_ids", [])

        answer_sort_cache_manager = AnswerSortCacheManager()
        answer_sort_cache_manager.calc_cache(question_id)
        check_spam.delay(answer_id, ['content'], DocType.ANSWER)

        # push to the question provider
        question_title = ''
        try:
            question = Question.objects.get(id=question_id)
            question_title = question.title
            if push_time_range_limit():
                push_to_question_provider(
                    user_id=question.user_id,
                    answer_id=answer_id,
                    question_title=question_title,
                    user_name=user.nick_name
                )
        except Question.DoesNotExist:
            logging_exception()
        # push to answerer fans
        common_push.delay(
            uname=user.nick_name,
            uid=user.id,
            topic_id=answer_id,
            push_type="answer",
            question_title=question_title
        )
        # kyc 流程自动触发灌水
        create_fake_task.delay(
            answer_id, COMMUNITY_CONTENT_TYPE.ANSWER, kwargs.get('level', CONTENT_CLASS.BAD),
            user.id
        )

    @classmethod
    def create(cls, user, question_id, content, images, platform, tags, **kwargs):
        """
        创建回答
        :param user:
        :param question_id:
        :param content:
        :param images:
        :param platform:
        :param tags:
        :return:
        """
        tag_v3_ids = kwargs.get("tag_v3_ids", [])
        v3_attr_tag_ids = kwargs.get("v3_attr_tag_ids", [])
        create_data = {
            "question_id": question_id,
            "content": content,
            "images": images,
            "platform": platform,
            "tag_ids": tags,
            "head_images": kwargs.get("head_images", []),
            "tag_v3_ids": tag_v3_ids,
            "v3_attr_tag_ids": v3_attr_tag_ids,
            "level": kwargs.get("content_level", CONTENT_CLASS.UNAUDITED)
        }
        try:
            results = cls._create_answer(user, create_data)
            answer_data = results.get("answer", {})

            cls.various_logic_after_answer_create(
                answer_data=answer_data,
                doctor=results.get("doctor", None),
            )
            cls.trigger_tasks_after_answer_reply_create(
                answer_data=answer_data,
                user=user,
                tag_ids=tags,
                tag_v3_ids=tag_v3_ids,
                level=kwargs.get("content_level", CONTENT_CLASS.BAD),
            )

            return answer_data
        except:
            logging_exception()
            return gen(ERROR.CONTENT_CREATE_ERROR)
