# coding: utf8
import json

import requests
from redlock import RedLock
from django.conf import settings


from gm_types.gaia import WECHAT_PLATFORM_TYPE

from rpc.decorators import bind
from rpc.tool.error_code import gen, CODES
from rpc.cache import wechat_auth_cache
from api.tool.log_tool import info_logger, logging_exception
from api.models.wechat import WechatAccountRelation

connection_detail = [settings.REDIS['wechat_token_lock']]


def _get_wechat_access_token():
    """
    获取access_token
    :return:
    """
    info_logger.info("request get wechat access token")
    wx_access_token_url = 'https://api.weixin.qq.com/cgi-bin/token'
    payload = {
        'appid': settings.WECHAT_SMALL_APPID,
        'secret': settings.WECHAT_SMALL_APPSECRET,
        'grant_type': 'client_credential'
    }
    result = requests.get(wx_access_token_url, params=payload).json()

    return result


def get_wechat_access_token():

    key = 'wechat_auth'
    with RedLock('wechat_auth_lock', connection_details=connection_detail, retry_delay=500) as L:
        cache = wechat_auth_cache.get(key)
        if cache:
            wx_auth = json.loads(cache)
        else:
            wx_auth = _get_wechat_access_token()
            wechat_auth_cache.setex(key, 60 * 60 * 1, json.dumps(wx_auth))
        # wx_auth = _get_wechat_access_token()
        return wx_auth.get('access_token')


def wechat_template_push(open_id, template_type, form_id, data):
    """
    小程序模板消息推送
    :param open_id: str
    :param template_type: template_type=vote 投票通知 template_check 为模板审核失败通知
    :param form_id: str
    :param data: dict
    :return:
    """
    if not all([open_id, data, template_type, form_id]):
        return gen(CODES.PARAMS_INCOMPLETE)

    access_token = get_wechat_access_token()

    # if not access_token:
    #     raise Exception('获取access_token失败！')
    # 小程序模板消息推送api
    url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={token}'
    if template_type == "vote":
        template_id = settings.TEMPLATE_VOTE_TEST if settings.DEBUG \
            else settings.TEMPLATE_VOTE
    elif template_type=="groupbuy":
        template_id = settings.TEMPLATE_VOTE_TEST if settings.DEBUG \
            else settings.TEMPLATE_GROUPBUY
    elif template_type == "template_check":
        template_id = settings.TEMPLATE_CHECK_TEST if settings.DEBUG \
            else settings.TEMPLATE_CHECK

    page = "/pages/activity/upload/main?from=notpk" if template_type == "template_check" \
        else "/pages/activity/viewResults/main?from_upgrade=1&from=level"
    push_data = {
        "touser": open_id,
        "template_id": template_id,
        "page": page,
        "form_id": form_id
    }
    push_data.update({'data': data})
    result = requests.post(
                url=url.format(token=access_token),
                data=json.dumps(push_data)
    )
    # error_code 为0 表示成功，其他为失败
    error_code = json.loads(result.content.decode('utf-8')).get('errcode', '')
    return error_code


def record_wechat_info(user_id, wechat_platform_type, unionid, openid):
    '''
    记录微信平台的unionid, openid对应关系
    :param wechat_paltform_type:
    :param unionid:
    :param openid:
    :return: None
    '''
    try:
        WechatAccountRelation.objects.update_or_create(
            wechat_platform_type=wechat_platform_type,
            user_id=user_id,
            defaults={'unionid': unionid, 'openid': openid}
        )
    except Exception as e:
        logging_exception()


def get_open_id_by_user_id(user_id, wechat_platform_type=WECHAT_PLATFORM_TYPE.GM_SMALL, app_id=None):
    '''
    根据user_id获取openid
    :param wechat_platform_type: 微信平台类型
    :param app_id: 应用id
    :return:
        eg: 'abd' | ''
    '''
    try:
        if not user_id:
            return ''

        if wechat_platform_type is None:
            if app_id:
                wechat_platform_type = WECHAT_PLATFORM_TYPE.get(app_id)
            else:
                wechat_platform_type = WECHAT_PLATFORM_TYPE.GM_SMALL
        if not wechat_platform_type:
            raise Exception('[WECHAT_ACCOUNT]can not get wechat_platform_type')

        war = WechatAccountRelation.objects.filter(user_id=user_id, wechat_platform_type=wechat_platform_type).first()
        if war:
            return war.openid
        return ''
    except Exception as e:
        logging_exception()
        return ''


def create_wx_qarcode(path, scene, width=280):
    """创建小程序二维码。"""

    url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={token}'
    token = get_wechat_access_token()
    data = {
        "scene": scene,
        "page": path,
        "width": width,
    }
    result = requests.post(
        url=url.format(token=token),
        data=json.dumps(data)
    )

    try:
        res = result.json()
        info_logger.info("createwxaqrcode error: {}".format(result.content))
        return {"errcode": res["errcode"], "errmsg": res["errmsg"]}
    except ValueError:
        buf = result.content
        return {"errcode": 0, "buffer": buf}
    except:
        logging_exception()
        return {"errcode": -1, "errmsg": "二维码生成出错"}
