# coding=utf-8

import json
import xmltodict

from django.db import transaction
from django.http import HttpResponse
from apps.customer import customer_log
from rest_framework.views import APIView

from utils.wx.WXBizMsgCrypt import WXBizMsgCrypt
from utils.exceptions import CustomError
from utils import response_ok, response_error
from utils.wechatpay import WechatPayNotify

from apps.log.models import BizLog
from apps.WechatTp.models import WechatTp
from apps.WechatApplet.models import WechatApplet
from apps.tenant.models import Tenant
from apps.pay.models import Pay
from apps.tenant.biz import TenantBiz
from utils.xgj.xgj import XGJ
from utils.permission import IsCustomerUser


class CallbackAuthorize(APIView):
    '''验证票据（component_verify_ticket）在第三方平台创建审核通过后，微信服务器会向其 ”授权事件接收URL”
    每隔 10 分钟以 POST 的方式推送 component_verify_ticket 接收 POST 请求后，只需直接返回字符串 success。
    为了加强安全性，postdata 中的 xml 将使用服务申请时的加解密 key 来进行加密'''

    def post(self, request):
        sMsgSignature = request.GET.get('msg_signature')
        sTimeStamp = request.GET.get('timestamp')
        sNonce = request.GET.get('nonce')
        sPostData = request.body.decode('utf-8')

        try:
            component = WechatTp.getDefault()
            if component:
                appid = component.getAppid()
                msg_crypt = WXBizMsgCrypt(component.getToken(), component.getEncodeKey(), appid)
                ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce)
                data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml']
                if data['AppId'] == appid:
                    if data['InfoType'] == 'component_verify_ticket':
                        component.refreshVerifyTicket(data['ComponentVerifyTicket'])
                    elif data['InfoType'] == 'unauthorized':
                        authorizer_appid = data['AuthorizerAppid']
                        authorizer = WechatApplet.getByAppidAndComponentAppid(authorizer_appid, appid)
                        if authorizer:
                            authorizer.revoke()
        except:
            pass

        return HttpResponse('success')


class RedirectAuthorize(APIView):
    '''小程序绑定授权回调'''

    def get(self, request, pk):
        try:
            with transaction.atomic():
                tenant = Tenant.objects.select_for_update().filter(id=pk).first()
                app = TenantBiz.bindWechatApplet(tenant, request.GET.get('auth_code'))
                BizLog.objects.addnew(None, None, BizLog.INSERT, u'租户绑定小程序, id=%d' % app.id)
        except Exception as e:
            return response_error(str(e))
        return response_ok()


class CallbackEvent(APIView):
    '''消息与事件接收'''

    def post(self, request, appid):
        appid = appid
        sMsgSignature = request.GET.get('msg_signature')
        sTimeStamp = request.GET.get('timestamp')
        sNonce = request.GET.get('nonce')
        sPostData = request.body.decode('utf-8')

        try:
            tp = WechatTp.getDefault()
            msg_crypt = WXBizMsgCrypt(tp.getToken(), tp.getEncodeKey(), tp.getAppid())
            ret, decryp_xml = msg_crypt.DecryptMsg(sPostData, sMsgSignature, sTimeStamp, sNonce)
            data = json.loads(json.dumps(xmltodict.parse(decryp_xml)))['xml']
            if data['MsgType'] == 'event':
                app = WechatApplet.getByAppid(appid)
                if data['Event'] == 'weapp_audit_success':  # 代码审核通过
                    app.weapp_audit_success()
                elif data['Event'] == 'weapp_audit_fail':  # 代码审核不通过
                    app.weapp_audit_fail(data['Reason'])
                elif data['Event'] == 'weapp_audit_delay':  # 代码审核延后
                    app.weapp_audit_delay(data['Reason'])
        except:
            pass
        return HttpResponse('success')

class WechatNotifyView(APIView):

    def dispatch(self, request, *args, **kwargs):
        appid = kwargs['appid']
        applet = WechatApplet.getByAppid(appid)
        param = request.body.decode('utf-8')
        notify = WechatPayNotify(param, applet.tenant_key)

        try:
            data = notify.handle()
            if not data:
                raise CustomError(u'错误的请求！')

            result_code = data['result_code']
            if result_code != 'SUCCESS':
                raise CustomError(u'错误的请求！')

            no = data['out_trade_no']
            amount = int(data['total_fee']) * 100

            with transaction.atomic():
                pay = Pay.getByNo(no)
                pay.payConfirm(amount)
                customer_log(pay.customer, BizLog.INSERT, u'支付成功，no=%s' % no, param)
        except:
            return HttpResponse(WechatPayNotify.response_fail())
        return HttpResponse(WechatPayNotify.response_ok())


class GetCompany(APIView):
    permission_classes = [IsCustomerUser, ]

    def get(self, request):
        appid = request.GET.get('appid')
        try:
            res = XGJ.get_company(appid)
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)


class GetMemberCard(APIView):
    permission_classes = [IsCustomerUser, ]

    def post(self, request):
        appid = request.POST.get('appid')
        company_id = request.POST.get('company_id')
        tel = request.POST.get('tel')
        number = request.POST.get('number')
        try:
            res = XGJ.get_member_card(appid, company_id, tel, number)
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)


class GetMemberInfo(APIView):
    permission_classes = [IsCustomerUser, ]

    def get(self, request):
        appid = request.GET.get('appid')
        customer = request.customer
        if not customer.member_id:
            raise CustomError(u'请先绑定会员卡')
        try:
            res = XGJ.get_member_info(appid, str(customer.member_id))
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)


class GetMemberPoints(APIView):
    permission_classes = [IsCustomerUser, ]

    def get(self, request):
        appid = request.GET.get('appid')
        page = request.GET.get('page')
        pageSize = request.GET.get('pageSize')
        customer = request.customer
        if not customer.member_id:
            raise CustomError(u'请先绑定会员卡')
        try:
            res = XGJ.get_member_points(appid, str(customer.member_id), page, pageSize)
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)


class GetMemberRecord(APIView):
    permission_classes = [IsCustomerUser, ]

    def get(self, request):
        appid = request.GET.get('appid')
        page = request.GET.get('page')
        pageSize = request.GET.get('pageSize')
        customer = request.customer
        if not customer.member_id:
            raise CustomError(u'请先绑定会员卡')
        try:
            res = XGJ.get_member_record(appid, str(customer.member_id), page, pageSize)
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)


class GetMemberBalance(APIView):
    permission_classes = [IsCustomerUser, ]

    def get(self, request):
        appid = request.GET.get('appid')
        customer = request.customer
        if not customer.member_id:
            raise CustomError(u'未绑定会员卡')
        try:
            res = XGJ.get_member_balance(appid, str(customer.member_id))
        except Exception as e:
            return response_error(str(e))
        return response_ok(res)

