import jingrow
import traceback
import urllib.parse
import json
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.util.SignatureUtils import verify_with_rsa
from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest

class AlipayAPI:
    def __init__(self):
        # 初始化时不立即加载设置
        self.client = None
        self.alipay_client_config = None
        self.return_url = None
        self.notify_url = None
        
    def _initialize(self):
        # 每次都重新加载配置，确保使用最新设置
        # 从 Jcloud Settings 获取配置
        settings = jingrow.get_single("Jcloud Settings")
        
        # 配置支付宝客户端
        self.alipay_client_config = AlipayClientConfig()
        self.alipay_client_config.server_url = settings.alipay_server_url
        self.alipay_client_config.app_id = settings.alipay_app_id
        self.alipay_client_config.app_private_key = settings.alipay_app_private_key
        self.alipay_client_config.alipay_public_key = settings.alipay_public_key
        
        # 存储默认回调URL
        self.return_url = settings.alipay_return_url
        self.notify_url = settings.alipay_notify_url
        
        # 初始化支付宝客户端
        self.client = DefaultAlipayClient(alipay_client_config=self.alipay_client_config)

    def generate_payment_url(self, order_id, amount, subject, team_name, return_url=None, notify_url=None):
        self._initialize()
        
        request = AlipayTradePagePayRequest()
        # 使用传入的URL或默认值
        request.return_url = return_url or self.return_url
        request.notify_url = notify_url or self.notify_url

        # 构建请求内容
        biz_content = {
            "out_trade_no": order_id,
            "total_amount": str(amount),
            "subject": subject,
            "product_code": "FAST_INSTANT_TRADE_PAY",
            "passback_params": urllib.parse.quote(team_name)  # 传递team_name并URL编码
        }
        
        # 直接赋值字典，不要进行JSON序列化
        request.biz_content = biz_content

        # 生成支付请求链接
        response = self.client.page_execute(request, http_method="GET")
        return response

    def verify_signature(self, data):
        """验证支付宝签名
        
        Args:
            data: 支付宝回调数据
            
        Returns:
            bool: 签名验证是否成功
        """
        self._initialize()
        
        try:
            signature = data.get('sign')
            # 使用辅助函数生成排序后的参数字符串
            org_message = get_dic_sorted_params(data)
            
            # 将字符串转换为字节用于验证
            message = bytes(org_message, encoding='utf-8')
            
            # 使用支付宝公钥验证签名
            result = verify_with_rsa(
                public_key=self.alipay_client_config.alipay_public_key,
                message=message,
                sign=signature
            )
            
            if result:
                jingrow.log_error("支付宝签名验证成功", "Alipay Signature")
            else:
                jingrow.log_error("支付宝签名验证失败", "Alipay Signature")
                
            return result
        except Exception as e:
            error_message = (
                "支付宝签名验证失败:\n"
                f"异常信息: {str(e)}\n"
                f"堆栈信息:\n{traceback.format_exc()}\n"
                f"回调数据: {data}\n"
            )
            jingrow.log_error(error_message, "Alipay Signature Error")
            return False

@jingrow.whitelist(allow_guest=True)
def alipay_notify():
    """支付宝回调接口"""
    try:
        # 验证签名
        api = AlipayAPI()
        if api.verify_signature(jingrow.form_dict):
            order_id = jingrow.form_dict['out_trade_no']
            trade_no = jingrow.form_dict['trade_no']
            trade_status = jingrow.form_dict['trade_status']

            if trade_status == 'TRADE_SUCCESS':
                # 更新订单状态
                order = jingrow.get_pg("Website Subscription", order_id)
                order.payment_status = "Paid"
                order.alipay_trade_no = trade_no
                order.save()

                # 开通网站 (付款成功后开通)
                if order.website_status != "Active":
                    order.website_status = "Active"
                    order.save()
                    jingrow.db.commit()
                    jingrow.log_error(f"网站 {order_id} 已成功激活", "Alipay Payment Success")
                
                return "success"
        else:
            jingrow.log_error("支付宝回调验证签名失败", "Alipay Notification")
    except Exception as e:
        jingrow.log_error(f"处理支付宝回调时出错: {str(e)}\n{traceback.format_exc()}", "Alipay Notification Error")
    
    return "fail"

# 接收字典类型参数，去除sign、sign_type字段，转换成升序字符串
def get_dic_sorted_params(org_dic_params):
    content = ''
    
    # 创建一个副本，确保不修改原始字典
    params = org_dic_params.copy()
    
    # 移除签名相关字段
    params.pop('sign', None)
    params.pop('sign_type', None)
    
    # 按键名升序排序
    new_list = sorted(params)
    for i in new_list:
        p = f"{i}={params.get(i)}&"
        content += p
    
    sorted_params = content.rstrip('&')
    return sorted_params
