package wechat

import (
	"context"
	"fmt"
	"github.com/go-pay/gopay"
	"github.com/go-pay/gopay/wechat/v3"
	"net/http"
	"time"
)

//基于此文档开发
//https://github.com/silenceper/wechat/blob/v2/doc/api/officialaccount.md
type wxpay struct {
	client   *wechat.ClientV3
	ctx      context.Context
	apiV3Key string
	MchId    string
}

var WxPay = wxpay{}

// Init 初始化
func (that *wxpay) Init(MchId, SerialNo, APIv3Key, PrivateKey string) {
	client, err := wechat.NewClientV3(MchId, SerialNo, APIv3Key, PrivateKey)
	if err != nil {
		//xlog.Error(err)
		fmt.Println(err)
		return
	}
	that.client = client
	that.apiV3Key = APIv3Key
	that.MchId = MchId
	// 设置微信平台API证书和序列号(如开启自动验签,请忽略此步骤)
	//client.SetPlatformCert([]byte(""), "")
	that.ctx = context.Background()
	// 启用自动同步返回验签,并定时更新微信平台API证书(开启自动验签时,无需单独设置微信平台API证书和序列号)
	err = client.AutoVerifySign()
	if err != nil {
		//xlog.Error(err)
		fmt.Println(err)
		return
	}

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

// GetUserInfo 获取用户信息
func (that *wxpay) GetJsOrder(money int64, appid, openid, name, tradeNo, notifyUrl string) (jsApiParams *wechat.JSAPIPayParams, err error) {
	fmt.Println("dasdas", money, appid, name, tradeNo, notifyUrl)
	PrepayId, err := that.getPrepayId(money, appid, that.MchId, openid, name, tradeNo, notifyUrl)
	if err != nil {
		return nil, err
	}

	//小程序
	jsapi, err := that.client.PaySignOfJSAPI(appid, PrepayId)
	return jsapi, err
}

func (that *wxpay) CallbackJsOrder(req *http.Request) (*wechat.V3DecryptResult, error) {

	notifyReq, err := wechat.V3ParseNotify(req)
	if err != nil {
		//xlog.Error(err)
		return nil, err
	}

	// wxPublicKey 通过 client.WxPublicKey() 获取
	err = notifyReq.VerifySignByPK(that.client.WxPublicKey())
	if err != nil {
		//xlog.Error(err)
		return nil, err
	}

	// ========异步通知敏感信息解密========
	// 普通支付通知解密
	result, err := notifyReq.DecryptCipherText(that.apiV3Key)

	//that.client.V3TransactionQueryOrder(that.ctx,result.BankType,result.OR)

	return result, err

	// 合单支付通知解密
	//result, err := notifyReq.DecryptCombineCipherText(apiV3Key)
	//// 退款通知解密
	//result, err := notifyReq.DecryptRefundCipherText(apiV3Key)

	// ========异步通知应答========
	// 退款通知http应答码为200且返回状态码为SUCCESS才会当做商户接收成功,否则会重试。
	// 注意:重试过多会导致微信支付端积压过多通知而堵塞,影响其他正常通知。

	// 此写法是 gin 框架返回微信的写法
	//c.JSON(http.StatusOK, &wechat.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
	//
	//// 此写法是 echo 框架返回微信的写法
	//return c.JSON(http.StatusOK, &wechat.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
}

// GetUserInfo 获取用户信息
//func (that *wxpay) GetMiniOrder(money int64,appid,name,tradeNo,notifyUrl string) (jsApiParams *wechat.AppletParams,err error){
//
//	PrepayId,err:=that.getPrepayId(money,name,tradeNo,notifyUrl)
//	if err!=nil{
//		return nil,err
//	}
//
//	//小程序
//	applet, err := that.client.PaySignOfApplet(appid,PrepayId)
//
//	return applet,err
//}

func (that *wxpay) getPrepayId(money int64, appid, mchid, openid, name, tradeNo, notifyUrl string) (prepayid string, err error) {
	expire := time.Now().Add(10 * time.Minute).Format(time.RFC3339)
	// 初始化 BodyMap
	bm := make(gopay.BodyMap)
	bm.Set("appid", appid).
		Set("mchid", mchid).
		//Set("sub_mchid", "sub_mchid").
		Set("description", name).
		Set("out_trade_no", tradeNo).
		Set("time_expire", expire).
		Set("notify_url", notifyUrl).
		SetBodyMap("amount", func(bm gopay.BodyMap) {
			bm.Set("total", money).
				Set("currency", "CNY")
		}).
		SetBodyMap("payer", func(bm gopay.BodyMap) {
			bm.Set("openid", openid)
		})
	//ctx:=context.Context()

	wxRsp, err := that.client.V3TransactionJsapi(that.ctx, bm)
	fmt.Println("获取PrepayId", wxRsp, err)
	if err != nil {
		//xlog.Error(err)
		return "", err
	}
	return wxRsp.Response.PrepayId, nil
}