package alipay

import (
	"context"
	"errors"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/alipay/v3"
	"github.com/go-pay/gopay/pkg/js"
	"goutil/logUtilPlus"
	"paycenter/internal/cert"
	"strconv"
)

var (
	ctx    = context.Background()
	client *alipay.ClientV3
	err    error
)

func init() {
	// 初始化支付宝客V3户端
	// appid：应用ID
	// privateKey：应用私钥，支持PKCS1和PKCS8
	// isProd：是否是正式环境，沙箱环境请选择新版沙箱应用。
	client, err = alipay.NewClientV3(cert.Appid, cert.PrivateKey, false)
	if err != nil {
		logUtilPlus.ErrorLog("new alipay client err:%s", err)
		return
	}

	// 自定义配置http请求接收返回结果body大小，默认 10MB
	//client.SetBodySize() // 没有特殊需求，可忽略此配置

	// Debug开关，输出/关闭日志
	client.DebugSwitch = gopay.DebugOn

	// 设置自定义RequestId生成方法
	//client.SetRequestIdFunc()

	// 设置biz_content加密KEY，设置此参数默认开启加密（目前不可用）
	//client.SetAESKey("KvKUTqSVZX2fUgmxnFyMaQ==")

	// 传入证书内容
	err = client.SetCert(cert.AppPublicContent, cert.AlipayRootContent, cert.AlipayPublicContentRSA2)
	if err != nil {
		logUtilPlus.ErrorLog("set cert err:%s", err)
		return
	}
}

// AliPayPlace 函数用于发起预支付请求。
// 参数:
//
//	outTradeNo: 商户订单号。
//	currency: 订单金额，单位为分。
//	storeId: 商户门店编号。
//	clientIp: 用户的客户端IP。
//	description: 订单描述。
//
// 返回值:
//
//	成功时返回预支付ID和nil错误。
//	失败时返回空字符串和错误对象。
func AliPayPlace(outTradeNo int64, currency int64, storeId string, clientIp string, description string) (string, error) {
	// 请求参数
	bm := make(gopay.BodyMap)
	bm.Set("subject", "预创建创建订单").
		Set("out_trade_no", strconv.FormatInt(outTradeNo, 10)).
		Set("total_amount", currency)

	rsp := new(struct {
		OutTradeNo string `json:"out_trade_no"`
		QrCode     string `json:"qr_code"`
	})
	// 创建订单
	res, err := client.DoAliPayAPISelfV3(ctx, alipay.MethodPost, alipay.V3TradePrecreate, bm, rsp)
	if err != nil {
		logUtilPlus.ErrorLog("client.TradePrecreate(), err:%v", err)
		return "", err
	}
	logUtilPlus.DebugLog("aliRsp:%s", js.Marshal(rsp))
	if res.StatusCode != alipay.Success {
		logUtilPlus.ErrorLog("aliRsp.StatusCode:%d", res.StatusCode)
		return "", errors.New("aliRsp.StatusCode:" + strconv.Itoa(res.StatusCode))
	}

	return "Success", nil
}
