package pay

import (
	"io/ioutil"
	"pay/conf"
	"pay/log"
	"pay/utils"

	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/alipay"
	"github.com/go-pay/gopay/wechat/v3"
)

type Pay struct {
	SingleAlipayClient    *alipay.Client
	SingleWechatpayClient *wechat.ClientV3
	MultiAlipayClient     *alipay.Client
	MultiWechatpayClient  *wechat.ClientV3
}

var SingleAlipayClient *alipay.Client
var SingleWechatpayClient *wechat.ClientV3
var MultiAlipayClient *alipay.Client
var MultiWechatpayClient *wechat.ClientV3

func NewPay(conf *conf.AppConf) *Pay {
	return &Pay{
		NewSingleAlipay(conf),
		NewSingleWechatPay(conf),
		NewMultiAlipay(conf),
		NewMultiWechatPay(conf),
	}
}

func NewSingleAlipay(conf *conf.AppConf) *alipay.Client {
	// 初始化支付宝客户端
	//    appid：应用ID
	//    privateKey：应用私钥，支持PKCS1和PKCS8
	//    isProd：是否是正式环境
	var err error
	singlePayCnf := utils.GetSinglePayConfig(conf)
	SingleAlipayClient, err = alipay.NewClient(singlePayCnf.AliPay.AppId, singlePayCnf.AliPay.PrivateKey, singlePayCnf.AliPay.IsProd)
	if err != nil {
		log.Errorf("支付宝客户端创建失败%v", err)
		return nil
	}
	// 打开Debug开关，输出日志，默认关闭
	SingleAlipayClient.DebugSwitch = gopay.DebugOn

	// 设置支付宝请求 公共参数
	//    注意：具体设置哪些参数，根据不同的方法而不同，此处列举出所有设置参数
	SingleAlipayClient.SetLocation(alipay.LocationShanghai). // 设置时区，不设置或出错均为默认服务器时间
									SetCharset(alipay.UTF8).                     // 设置字符编码，不设置默认 utf-8
									SetSignType(alipay.RSA2).                    // 设置签名类型，不设置默认 RSA2
									SetReturnUrl(singlePayCnf.AliPay.ReturnUrl). // 设置返回URL
									SetNotifyUrl(singlePayCnf.AliPay.NotifyUrl)  // 设置异步通知URL
	//							SetAppAuthToken("cbeae4203632449198fd10886456bD50") // 设置第三方应用授权

	// 自动同步验签（只支持证书模式）
	// 传入 alipayCertPublicKey_RSA2.crt 内容
	fileData, err := ioutil.ReadFile(singlePayCnf.AliPay.AliPayPublicCertPath)
	if err != nil {
		log.Errorf("自动验签错误%v", err)
	}
	SingleAlipayClient.AutoVerifySign(fileData)
	// 公钥证书模式，需要传入证书，以下两种方式二选一
	// 证书路径
	err = SingleAlipayClient.SetCertSnByPath(singlePayCnf.AliPay.AppCertPath, singlePayCnf.AliPay.AliPayRootCertPath, singlePayCnf.AliPay.AliPayPublicCertPath)
	if err != nil {
		log.Errorf("证书导入错误%v", err)
	}
	return SingleAlipayClient
}

func NewSingleWechatPay(conf *conf.AppConf) *wechat.ClientV3 {

	var err error
	singlePayCnf := utils.GetSinglePayConfig(conf)
	PrivateKey, _ := ioutil.ReadFile(singlePayCnf.WechatPay.PrivateKey)
	SingleWechatpayClient, err = wechat.NewClientV3(singlePayCnf.WechatPay.MchId, singlePayCnf.WechatPay.SerialNo, singlePayCnf.WechatPay.ApiV3Key, string(PrivateKey))
	if err != nil {
		log.Error(err)
		return nil
	}

	// 设置微信平台API证书和序列号（如开启自动验签，请忽略此步骤）
	//client.SetPlatformCert([]byte(""), "")

	// 启用自动同步返回验签，并定时更新微信平台API证书（开启自动验签时，无需单独设置微信平台API证书和序列号）
	err = SingleWechatpayClient.AutoVerifySign()
	if err != nil {
		log.Error(err)
	}

	// 打开Debug开关，输出日志，默认是关闭的
	SingleWechatpayClient.DebugSwitch = gopay.DebugOn
	return SingleWechatpayClient
}

func NewMultiAlipay(conf *conf.AppConf) *alipay.Client {
	// 初始化支付宝客户端
	//    appid：应用ID
	//    privateKey：应用私钥，支持PKCS1和PKCS8
	//    isProd：是否是正式环境
	var err error
	multiCnf := utils.GetMultiPayConfig(conf)
	MultiAlipayClient, err = alipay.NewClient(multiCnf.AliPay.AppId, multiCnf.AliPay.PrivateKey, multiCnf.AliPay.IsProd)
	if err != nil {
		log.Errorf("支付宝客户端创建失败%v", err)
	}
	// 打开Debug开关，输出日志，默认关闭
	MultiAlipayClient.DebugSwitch = gopay.DebugOn

	// 设置支付宝请求 公共参数
	//    注意：具体设置哪些参数，根据不同的方法而不同，此处列举出所有设置参数
	MultiAlipayClient.SetLocation(alipay.LocationShanghai). // 设置时区，不设置或出错均为默认服务器时间
								SetCharset(alipay.UTF8).                 // 设置字符编码，不设置默认 utf-8
								SetSignType(alipay.RSA2).                // 设置签名类型，不设置默认 RSA2
								SetReturnUrl(multiCnf.AliPay.ReturnUrl). // 设置返回URL
								SetNotifyUrl(multiCnf.AliPay.NotifyUrl)  // 设置异步通知URL
		// SetAppAuthToken(multiCnf.AliPay.AppAuthToken)

	// 自动同步验签（只支持证书模式）
	// 传入 alipayCertPublicKey_RSA2.crt 内容
	fileData, err := ioutil.ReadFile(multiCnf.AliPay.AliPayPublicCertPath)
	if err != nil {
		log.Errorf("自动验签错误%v", err)
	}
	MultiAlipayClient.AutoVerifySign(fileData)
	// 公钥证书模式，需要传入证书，以下两种方式二选一
	// 证书路径
	err = MultiAlipayClient.SetCertSnByPath(multiCnf.AliPay.AppCertPath, multiCnf.AliPay.AliPayRootCertPath, multiCnf.AliPay.AliPayPublicCertPath)
	if err != nil {
		log.Errorf("证书导入错误%v", err)
	}
	return MultiAlipayClient
}

func NewMultiWechatPay(conf *conf.AppConf) *wechat.ClientV3 {
	multiCnf := utils.GetMultiPayConfig(conf)
	PrivateKey, _ := ioutil.ReadFile(multiCnf.WechatPay.PrivateKey)
	var err error
	MultiWechatpayClient, err = wechat.NewClientV3(multiCnf.WechatPay.MchId, multiCnf.WechatPay.SerialNo, multiCnf.WechatPay.ApiV3Key, string(PrivateKey))
	if err != nil {
		log.Error(err)
	}

	// 设置微信平台API证书和序列号（如开启自动验签，请忽略此步骤）
	//client.SetPlatformCert([]byte(""), "")

	// 启用自动同步返回验签，并定时更新微信平台API证书（开启自动验签时，无需单独设置微信平台API证书和序列号）
	err = MultiWechatpayClient.AutoVerifySign()
	if err != nil {
		log.Error(err)
	}

	// 打开Debug开关，输出日志，默认是关闭的
	MultiWechatpayClient.DebugSwitch = gopay.DebugOn
	return MultiWechatpayClient
}

func (*Pay) Connect() {
	log.Info("初始化支付客户端")
}
