# -*- coding:utf-8 -*-

from kyger.utility import *
from kyger.parser_ini import Config
from kyger.common import xml_data
from tools import qrcode, six
import json


class WxPay(object):
    """微信支付类"""

    # 构造函数
    def __init__(self, db=None, kg=None):
        # 数据库
        from kyger.db import MySQL
        import socket
        self.db = db if db else MySQL()  # 数据库操作对象
        self.kg = kg  # 全局变量
        self.wx = Config('/config/settings.ini').get('wxpay')  # 读取配置文件
        myaddr = socket.getaddrinfo(url_parse(self.kg['server']['HTTP_HOST'], 'netloc'), 'http')
        self.ip = myaddr[0][4][0]

    def get_sign(self, params):
        """
        签名函数
        :param params: [dict] 参数
        :return:
        """
        params_list = sorted(params.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表
        params_list.append(('key', self.wx.get('key', '')))
        key_val_list = []
        for var in params_list:
            key_val_list.append('%s=%s' % (var[0], var[1]))
        return md5('&'.join(key_val_list)).upper()

    @staticmethod
    def trans_dict_to_xml(data_dict):
        """
        定义字典转XML的函数
        :param data_dict: [dict]
        :return:
        """
        data_xml = []
        for k in sorted(data_dict.keys()):  # 遍历字典排序后的key
            v = data_dict.get(k)  # 取出字典中key对应的value
            if k == 'detail' and not v.startswith('<![CDATA['):  # 添加XML标记
                v = '<![CDATA[{}]]>'.format(v)
            data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
        return '<xml>{}</xml>'.format(''.join(data_xml))  # 返回XML

    def wxpay(self, oid, total_fee, body):

        # 判断二维码是否已经有
        files = file_list('upload/other', 1, 0)
        for file in files:
            if file.startswith(oid):
                return {'status': 'success', 'qrcode': '/upload/other/' + file}

        params = {
            'appid': self.wx.get('appid', ''),  # APPID
            'mch_id': self.wx.get('mchid', ''),  # 商户号
            'nonce_str': str_random(8, 3, 1),  # 随机字符串
            'out_trade_no': oid,  # 订单编号，可自定义
            'total_fee': total_fee,  # 订单总金额,单位分
            'spbill_create_ip': self.ip,  # 自己服务器的IP地址
            'notify_url': self.kg['server']['HTTP_HOST'] + self.wx.get('url', ''),  # 回调地址，微信支付成功后会回调这个url，告知商户支付结果
            'body': body,  # 商品描述
            'detail': 'xxx商品',  # 商品描述
            'trade_type': 'NATIVE',  # 扫码支付类型
            'time_expire': date(int(self.kg['run_start_time'][1]) + 1800, '%Y%m%d%H%M%S')
        }

        # 签名
        params['sign'] = self.get_sign(params)

        # xml数据拼接
        xml_code = self.trans_dict_to_xml(params)

        # 发送请求
        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        res = xml_data(get_contents(url, data=xml_code, method='POST'))

        if res.get('return_code') == 'SUCCESS':
            # 请求成功
            img = qrcode.make(res.get('code_url'))  # 创建支付二维码片
            img.save(url_absolute('upload/other/%s.png' % oid))
            return {'status': 'success', 'qrcode': '/upload/other/%s.png' % oid}
        else:
            return {'status': 'failure', 'msg': res.get('return_msg', 'unknown error')}


class AliPay(object):
    """阿里支付类"""

    # 构造函数
    def __init__(self, db=None, kg=None):
        # 数据库
        from kyger.db import MySQL
        self.db = db if db else MySQL()  # 数据库操作对象
        self.kg = kg  # 全局变量
        self.ali = Config('/config/settings.ini').get('alipay')  # 读取配置文件
        self.public_param = {
            "app_id": self.ali['appid'],
            "method": '',  #
            "notify_url": self.kg['server']['HTTP_HOST'] + '/api/paycheck',
            "charset": 'utf-8',
            "sign_type": "RAS2",
            # "sign": '',
            "timestamp": date(int(self.kg['run_start_time'][1]), '%Y-%m-%d %H:%M:%S'),
            "version": "1.0",
            "biz_content": ''  #
        }


    def api_alipay_trade_page_pay(self, subject, out_trade_no, total_amount):
        biz_content = {
            "subject": subject,  # d]订单标题
            "out_trade_no": out_trade_no,  # 商户订单号
            "total_amount": total_amount,  # 订单总金额
            "product_code": "FAST_INSTANT_TRADE_PAY",  # 销售产品码
        }
        self.public_param['method'] = 'alipay.trade.page.pay'
        self.public_param['biz_content'] = biz_content

        return self.sign_data(data)

    def sign_data(self, data):
        # 排序
        complex_keys = [k for k, v in data.items() if isinstance(v, dict)]

        # 将字典类型的数据dump出来
        for key in complex_keys:
            data[key] = json.dumps(data[key], separators=(',', ':'))

        # 排序后的字符串
        ordered_items = sorted([(k, v) for k, v in data.items()])
        unsigned_string = "&".join("{}={}".format(k, v) for k, v in ordered_items)
        sign = self._sign(unsigned_string)
        quoted_string = "&".join("{}={}".format(k, quote_plus(v)) for k, v in ordered_items)

        # 获得最终的订单信息字符串
        signed_string = quoted_string + "&sign=" + quote_plus(sign)
        return signed_string

