#橙券支付
#中数科支付
#接口文档 https://doc.apipost.net/docs/detail/34ff33e7bce7000?target_id=ef551d7ba901a

import hashlib
import datetime
import time
import json 
import urllib.request
import urllib.parse
import random
import base64
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding



env = 'dev'
domain='http://ywymtest-api.azhiyun.cn'

sign = {
    'dev': {
        'ym-id': '645206198756315136',
        'ym-key': '15a5ba24711540f0bd3246b92a7c7daa'
    },
    'prod':{}
}


class ZSKPay:

    def __init__(self):
        self.MAX_ENCRYPTION_SIZE = 117 #214

    # 计算签名
    def generate_sign(self,data):
        # # 1. 整理参数
        # sorted_keys = sorted(data.keys())
        # sorted_data = []
        # for key in sorted_keys:
        #     sorted_data.append(f"{key}={data[key]}")
        # # 2. 连接参数
        # params_string = '&'.join(sorted_data)
        # # 3. 添加签名秘钥
        # params_string += f"&key={self.k}"
        # # 4. MD5 加密
        # sign = hashlib.md5(params_string.encode('utf-8')).hexdigest().upper()
        
        return 'sign'

    def encrypt_data(self, data):
        encrypted_chunks = []
        current_directory = os.getcwd()
        with open(current_directory+"/wx/cert/zsk/req/public_key.txt", "rb") as public_file:
            public_key_content = public_file.read()
        
        public_key_loaded = serialization.load_pem_public_key(
            public_key_content,
            backend=default_backend()
        )

        # 将数据分块
        for i in range(0, len(data), self.MAX_ENCRYPTION_SIZE):
            chunk = data[i:i + self.MAX_ENCRYPTION_SIZE]

            try:
                # 使用公钥加密内容
                ciphertext = public_key_loaded.encrypt(
                    chunk,
                    padding.PKCS1v15()
                )
                encrypted_chunks.append(ciphertext)
            except Exception as e:
                print("加密块失败:", e)

        # 将所有加密后的块连接在一起
        resp = b''.join(encrypted_chunks)
        return base64.b64encode(resp).decode('utf-8')


    def decrypt_data(self, data):
        current_directory = os.getcwd()
        with open(current_directory+"/wx/cert/zsk/resp/private_key.txt", "rb") as public_file:
            private_key_content = public_file.read()
        
        # 加载私钥
        private_key_loaded = serialization.load_pem_private_key(
            private_key_content,
             password=None,
            backend=default_backend()
        )
        # 解密
        data = json.jmson.loads(data)
        plaintext = private_key_loaded.decrypt(
            base64.b64decode(data),
            padding.PKCS1v15()
        )
        return plaintext.decode('utf-8')

    def http_post(self, data={}, url=''):
        data =  json.dumps(data).encode('utf-8')
        # 加密数据
        data = self.encrypt_data(data)
        # print("加密后数据:", type(data), data)
        headers = {
            'Content-Type': 'application/json',
            **sign[env]
        }   
        
        request = urllib.request.Request(domain + url, bytes(json.dumps({'data': data}), "utf8"), headers, method='POST')
        # 发送请求并获取响应
        try:
            response = urllib.request.urlopen(request)
            
            # 读取响应体
            res_body = response.read().decode('utf-8')
            print("返回结果:", res_body)
            
            return json.loads(res_body)

        except urllib.error.HTTPError as e:
            print("HTTP错误:", e.code, e.read().decode())
        except urllib.error.URLError as e:
            print("网络错误:", e.reason)
    
    #转账
    def transfer(self,data):
        print('开始转账:')
        handle_data = {
            "taxId": 1836580691238883330,
            "batchNo":data.get('batchNo', self.generate_batchNo()),
            "appid": data.get('appid','wxb8516c6064271fe4'),
            "batchName": data.get('batchName','活动批次'),
            "batchRemark": data.get('batchRemark','默认备注'),
            "totalAmount": 0,
            "totalNum": 0,          #转账总笔数
            "transferSceneId": "",  #转账场景ID
            "notifyUrl": "",        #回调地址
            #转账明细列表
            "transferDetailList":data.get('transferDetailList',[])
            # [
            #     {
            #         "transferNo": "tj_consumer_winner_001", //商家明细单号
            #         "transferAmount": 30, //转账金额单位为“分”
            #         "transferRemark": "红包", //转账备注,【转账备注】 单条转账备注（微信用户会收到该备注），UTF8编码，最多允许32个字符
            #         "openid": "oCZuC5RiJ8RId4qacC0inhy74vRc", //【收款用户openid】商户appid下，某用户的openid
            #         "userName": "
            #     }
            # ]
        }
        if len(data['transferDetailList']) == 0:
            raise ValueError("transferDetailList 必传")
        for item in data['transferDetailList']:#计算总金额和总笔数
            # if not item.get('transferNo') or not item.get('transferAmount') or not item.get('transferRemark') or not item.get('openid'):
            #     raise ValueError("缺少转账参数")
            handle_data['totalAmount'] += item['transferAmount']
            handle_data['totalNum'] += 1

        print('加密前数据----:',handle_data)
        return self.http_post(data=handle_data,url='/wx-pay/transfer')
    
    #转账信息查询
    def tranfer_info(self,data={}):
        if not data.get('batchNo') or data.get('batch',''):
            raise ValueError("缺少参数")
        encrypt_body = self.http_post(data=data,url='/wx-pay/transfer-info')
        decrypted_body = self.decrypt_data(encrypt_body['data'])
        print('解密后的查询数据',decrypted_body)
        return json.loads(decrypted_body)
        
    # 生成订单号
    def generate_batchNo():
        timestamp = int(time.time())
        random_number = random.randint(1000, 9999)
        batchNo ='tj'+ str(timestamp) + str(random_number)
        return batchNo


