# -*- coding: utf-8 -*-
import random
import json
import time
import traceback
from rpc.tool.error_code import gen
from rpc.decorators import bind, bind_context
from api.models.face.nanshen_shouge import (
    NanshenQuestion,
    NanshenAnswer,
    NanshenFaceType,
    UnlockRecord,
    ShareRecord,
    NanshenReport
)

from gm_types.gaia import (
    CONTOUR_TYPE,
    EYE_TYPE,
    EYEBROW_TYPE,
    NOSE_TYPE,
    LIP_TYPE,
    CHIN_TYPE
)

from django.conf import settings
from api.tool.user_tool import get_user_from_context
from django.db.models import Q
from gm_types.error import ERROR as CODES
from rpc.tool.log_tool import ai_logger
from api.util.user_util import get_open_id_by_user_id
from utils.wechat_applet_tools import applet_template_push


@bind('api/nanshen_activite/question')
def nanshen_activite_get_question():
    """
    男神收割机需求问题列表
    :return:
    """
    questions = NanshenQuestion.objects.filter(is_online=True)
    data = []
    for item in questions:
        data.append({
            "id": item.id,
            "question": item.question,
            "choices": [item.choice1, item.choice2]
        })
    return {"questions": data}


@bind_context('api/nanshen_activite/create_share', login_required=True)
def nanshen_activite_create_share(
        ctx,
        eye,
        contour,
        answers,
        user_name,
        user_icon,
        user_face_image,
        form_id=''
):
    """
    男神收割机需求根据用户创建分享
    :return:
    """
    user = get_user_from_context(ctx)
    if not user:
        return gen(CODES.MESSAGE_UNKNOWN_USER)
    result = _nanshen_activite_get_result(eye, contour, answers, user_face_image)
    answer_vectors = _get_answer_vectors_and_type(answers)
    share_info = []

    def _get_outside_data(out_id):
        obj = NanshenFaceType.objects.get(id=out_id)
        out_data = [{
            "vector_name": u"颜值",
            "keyword": random.sample(
                [
                    CONTOUR_TYPE.getDesc(obj.contour),
                    CHIN_TYPE.getDesc(obj.chin),
                    EYE_TYPE.getDesc(obj.eye),
                    EYEBROW_TYPE.getDesc(obj.eyebrow),
                    NOSE_TYPE.getDesc(obj.nose),
                    LIP_TYPE.getDesc(obj.lip)
                ],
                2
            ),
            "content": obj.content,
        }]
        return out_data

    share_info.extend(_get_outside_data(result["out_id"]))

    def _get_inner_vector_desc(vectors=answer_vectors):
        """
        返回对应的关键词，维度名称， 维度文案按照ABCD的顺序返回
        :param vectors:
        :return:
        """
        inner_data = []
        query = Q()
        for k, v in vectors.items():
            query |= (Q(vector=k) & Q(vector_type=v))
        query &= Q(is_online=True)

        objs = NanshenReport.objects.filter(query).order_by("vector")
        for obj in objs:
            inner_data.append({
                "vector_name": obj.vector_name,
                "content": random.sample([obj.content1, obj.content2], 1)[0],
                "keyword": random.sample(obj.keyword.split(","), 2) if len(
                    obj.keyword.split(",")) > 1 else obj.keyword.split(",")
            })
        return inner_data

    share_info.extend(_get_inner_vector_desc(vectors=answer_vectors))

    obj = ShareRecord.objects.create(
        user_id=user.id,
        user_name=user_name,
        user_icon=user_icon,
        unlock_content=json.dumps(share_info),
        content=json.dumps(result),
        is_online=True,
        form_id=form_id
    )
    result.update({"share_info": share_info, "share_id": obj.id})
    return result


@bind('api/nanshen_activite/get_share')
def nanshen_activite_get_inner_type(share_id):
    """
    男神收割机需求  获取用户分享数据
    :return:
    """
    obj = ShareRecord.objects.get(Q(id=share_id) & Q(is_online=True))
    unlock_list = list(UnlockRecord.objects.filter(unlock=obj.id).values(
        "user_name", "user_icon", "user_id"
    ))
    # share_cnt = UnlockRecord.objects.filter(unlock=obj.id).count()
    return {
        # "share_cnt": share_cnt,
        "user_id": obj.user_id,
        "unlock_list": unlock_list,
        "share_cnt": len(unlock_list),
        "content": json.loads(obj.content),
        "unlock_content": json.loads(obj.unlock_content),
        "user_name": obj.user_name,
        "user_icon": obj.user_icon
    }


@bind_context('api/nanshen_activite/unlock', login_required=True)
def nanshen_activite_unlock(ctx, user_name, user_icon, unlock_id, access_token):
    """
    男神收割助力解锁
    :param ctx:
    :param filters:
    :return:
    """

    user = get_user_from_context(ctx)
    if not user:
        return gen(CODES.MESSAGE_UNKNOWN_USER)
    filters = {
        "is_online": True, "user_id": user.id, "user_name": user_name, "user_icon": user_icon, "unlock_id": unlock_id
    }
    _, created = UnlockRecord.objects.get_or_create(**filters)
    _send_template_msg(user_name, unlock_id, access_token)
    return created


@bind_context('api/nanshen_activite/get_last_share', login_required=True)
def nanshen_activite_get_last_share(ctx):
    """
    获取最近的一次分享
    :param ctx:
    :param filters:
    :return:
    """

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

    obj = ShareRecord.objects.filter(user_id=user.id).order_by("-id").first()
    result = {
        "share_id": obj.id if obj else 0
    }

    return result


def _nanshen_activite_get_result(eye, contour, answers, user_face_image):
    """
    用户回答完问题的时候返回这些数据，当用户分享的时候，需要增加更多的文案信息

    :param eye:
    :param contour:
    :param answers:
    :return:
    """
    answer_vectors = _get_answer_vectors_and_type(answers)

    def get_inner_image_and_nanshen(vectors=answer_vectors):
        """
        返回内心可俘获男神与男神的图片
        根据传入的问题的答案，处理出对应的四个维度
        A 对应维度1，  B 对应维度2， C对应维度3  D对应维度4
        :return:
        """
        vector1, vector2, vector3, vector4 = vectors.get("A"), vectors.get("B"), vectors.get("C"), vectors.get("D")
        query = Q(is_online=True) & Q(vector1=vector1) & Q(vector2=vector2) & Q(vector3=vector3) & Q(vector4=vector4)
        obj = NanshenAnswer.objects.filter(query).first()
        return {"image": obj.celebrity_image, "nanshen": obj.nanshen, "inner_id": obj.id}

    inner_image_and_nanshen = get_inner_image_and_nanshen(answer_vectors)

    def get_outside_image_and_nanshen_and_face_type(eye, contour):
        ai_logger.info("get nanshen type, eye:{}, contour:{}".format(eye, contour))
        obj = NanshenFaceType.objects.filter(
            contour=_get_enum_index(CONTOUR_TYPE, contour),
            eye=_get_enum_index(EYE_TYPE, eye),
            is_online=True
        ).first()
        if not obj:
            ai_logger.info("nanshen type not found!")
            return gen(CODES.FENXIAO_WANGHONG_NOT_EXIST)  # todo: 添加错误枚举

        return {"outside_id": obj.id, "nanshen": obj.nanshen, "image": obj.celebrity_image, "face_type": obj.face_type}

    outside_image_and_nanshen_and_face_type = get_outside_image_and_nanshen_and_face_type(eye, contour)

    result = {}
    result.update({
        "in_id": inner_image_and_nanshen["inner_id"],
        "in_nanshen": inner_image_and_nanshen["nanshen"],
        "in_image": inner_image_and_nanshen["image"],
        "out_id": outside_image_and_nanshen_and_face_type["outside_id"],
        "out_nanshen": outside_image_and_nanshen_and_face_type["nanshen"],
        "out_image": outside_image_and_nanshen_and_face_type["image"],
        "out_face_type": outside_image_and_nanshen_and_face_type["face_type"],
        "user_face_image": user_face_image,
    })

    return result


def _get_answer_vectors_and_type(answers):
    """
    input : [[],[]]
    :return: {'A': u'1', 'B': u'1', 'C': '', 'D': ''}
    维度A有两个不同的选项, 则使用type1，维度A有两个相同的选项, 则使用相同的
    最后返回的数据是 四个维度对应的类型
    让产品使用枚举不使用，非要搞自己在后台填写
    """
    query = Q(is_online=True) & Q(id__in=[item["id"] for item in answers])
    answer_list = NanshenQuestion.objects.filter(query).values("id", "vector", "type1", "type2")

    qa_dict = {item["id"]: item["choice"] for item in answers}
    result = {"A": ["", ""], "B": ["", ""], "C": ["", ""], "D": ["", ""], }
    for item in answer_list:
        choice = "type2" if qa_dict[item["id"]] else "type1"  # 选项0 代表type1  1 代表type2
        result[item["vector"]][qa_dict[item["id"]]] = item[choice]
    for _, v in result.items():
        result[_] = v[0] if v[0] else v[1]
    return result


def _get_enum_index(enum_type, enum_value):
    for item in enum_type:
        if item[1] == enum_value:
            return item[0]
    return enum_value


def _send_template_msg(user_name, unlock_id, access_token):
    try:
        record = ShareRecord.objects.filter(id=unlock_id).first()
        if not record:
            ai_logger.error("ShareRecord not found, id: {}".format(unlock_id))

        unlock_count = UnlockRecord.objects.filter(unlock_id=unlock_id).count()
        if unlock_count < settings.PRINCE_UNLOCK_TIMES:
            template_id = settings.PRINCE_TEMPLATE_MESSAGE_ID_COMPLETING
            data = {
                "keyword1": {
                    "value": time.strftime("%Y/%m/%d %H:%M", time.localtime())
                },
                "keyword2": {
                    "value": u"助力成功"
                },
                "keyword3": {
                    "value": u"【{}】".format(user_name)
                },
                "keyword4": {
                    "value": u"您的好友【{}】已成功为您助力，还差{}位好友助力就可解锁详细报告了。快去群里叫人吧！".format(
                        user_name, settings.PRINCE_UNLOCK_TIMES - unlock_count
                    )
                },
            }

        else:
            template_id = settings.PRINCE_TEMPLATE_MESSAGE_ID_COMPLETE
            data = {
                "keyword1": {
                    "value": u"【男神收割机】详细报告已解锁"
                },

                "keyword2": {
                    "value": u"您的好友太给力了，已完成助力为你解锁详细报告，快来查看吧！"
                },
            }

        open_id = get_open_id_by_user_id(record.user_id)
        if not open_id:
            return

        applet_template_push(
            access_token,
            open_id,
            template_id,
            record.form_id,
            data=data,
            page="packageActivity/pages/peach/report/main?ref=push&share_id={}".format(unlock_id)
        )
    except:
        ai_logger.error(traceback.format_exc())
