package pay

import (
	"crypto"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"io/ioutil"
	"strings"
	"system_pay/controller/base"
	"system_pay/models"
	"system_pay/repository/pay"
)

// 卡拉卡统一支付回调
type NoticeController struct {
}

// WxNotice 拉卡拉统一支付微信回调
// @Summary 拉卡拉统一支付微信回调
// @Description 拉卡拉统一支付微信回调
// @Tags 拉卡拉统一支付回调
// @Accept application/json
// @Produce application/json
// @Param   body    body  models.WxNoticeInput   true	 "参数"
// @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja-JP日文 默认中文"
// @Success 200
// @router /api/v1/pay/wx_notice [post]
func (l *PayController) WxNotice(c *gin.Context) {
	fmt.Println("拉卡拉微信回调start")

	//验证签名
	err := VerifySignCert(c)
	if err != nil {
		fmt.Println("verySignByPublicKey err: ", err)
		response := new(base.ResponseDataWxNotice)
		response.Code = "FAIL"
		response.Message = "验证签名失败"
		base.ResponseWxNotice(c, response)
		return
	}

	//fmt.Println("验证签名成功...未完...")
	//response := new(base.ResponseDataWxNotice)
	//response.Code = "SUCCESS"
	//response.Message = "执行成功"
	//base.ResponseWxNotice(c, response)
	//return

	fmt.Println("验证签名成功")

	ph := new(models.WxNoticeInput)
	//err := c.ShouldBindJSON(ph)
	err = c.ShouldBindBodyWith(&ph, binding.JSON)
	if err != nil {
		response := new(base.ResponseDataWxNotice)
		response.Code = "FAIL"
		response.Message = "执行失败2"
		base.ResponseWxNotice(c, response)
		return
	}
	fmt.Println(ph)

	// 拉卡拉统一支付微信回调
	response, err := pay.WxNotice(ph)

	fmt.Println("拉卡拉微信回调end")
	base.ResponseWxNotice(c, response)
}

//读取证书文件,验证签名
func VerifySignCert(c *gin.Context) error {
	// 1、读取证书文件,获取证书字节
	certPEM, err := ioutil.ReadFile("./cert/dev/lkl-apigw-v2.cer") //测试
	//certPEM, err := ioutil.ReadFile("./cert/prod/dbc/lkl-apigw-v1.cer") //正式
	if err != nil {
		fmt.Println("ioutil.ReadFile failed")
		return err
	}

	block, _ := pem.Decode([]byte(certPEM))
	if block == nil {
		fmt.Println("failed to parse certificate PEM")
		return errors.New("failed to parse certificate")
	}
	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		fmt.Println("failed to parse certificate: " + err.Error())
		return err
	}

	authorization := c.GetHeader("Authorization")
	fmt.Println("wangpei test 验证签名0...")
	fmt.Println("Authorization1="+authorization)

	authorization = strings.Replace(authorization, "LKLAPI-SHA256withRSA ", "", -1)
	authorization = strings.Replace(authorization, ",","&", -1)
	authorization = strings.Replace(authorization, "\"","", -1)

	//authorization = "timestamp=1689752771&nonce_str=5HO2w0AjbhJc&signature=VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw=="

	auth_parts := strings.Split(authorization, "&")
	params := make(map[string]string)
	for _, param := range auth_parts {
		item := strings.Split(param, "=")
		params[item[0]] = item[1]
	}
	//if params["signature"] != "" && len(params["signature"]) > 10 {
	//	//params["signature"] = substr($query, strrpos($query, 'signature=') + 10);
	//	params["signature"] = params["signature"][0:10]
	//}
	timestamp := params["timestamp"]
	nonce := params["nonce_str"]
	signature := params["signature"]
	signature = signature + "=="
	//signature = "VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw=="

	//b, err := c.GetRawData()
	//if err != nil {
	//	fmt.Println("failed to get request body: " + err.Error())
	//	return err
	//}
	//reqBody := string(b) //获取response body

	var body interface{}
	err = c.ShouldBindBodyWith(&body, binding.JSON)
	if err != nil {
		//log.Default().Error("should bind body error", zap.Error(err))
		fmt.Println("should bind body error: " + err.Error())
		return err
	}
	byteBody, err := json.Marshal(body)
	if err != nil {
		fmt.Println("json.Marshal error: " + err.Error())
		return err
	}
	reqBody := string(byteBody)
	//reqBody, _ := json.MarshalToString(body)

	//JAVA demo
	//timestamp = "1630905585";
	//nonce = "9003323344";
	//signature = "tnjIAcEISq/ClrOppv/nojeZnE/pB1wNfQC/hMTME+rQMapWzvs9v1J68ueDpVzs1RW22dNotmUVy2sM6thNFRkaOx4qQGslX6kIttwvlsJsSEIR3qrjdPdUAkbP2KDRLujspxE9X0daJ6BU+rOoJ8p4c6y1/QSOMtDJoO3EABOF4O6RFHR3N7JW8o4qcf7lOOO7D4rlAB2vw6tV8WeG+OEyJ++Q0K3V1oM5uJEIPPuJkb2qlEqVYKiYLyvIdEJ1Z5qMbC9U7rKuHdeTQPl7last/h5nd6WauzDfYPKlAjZBEPYjiDqRv6Dm+4FeNtALoy6Mg7Ruxeq1pJudfj0iKg==";
	//reqBody = "{\"payOrderNo\":\"21090611012001970631000463034\",\"merchantOrderNo\":\"CH2021090613190866292\",\"orderInfo\":null,\"merchantNo\":\"822126090640003\",\"termId\":\"47781282\",\"tradeMerchantNo\":\"822126090640003\",\"tradeTermId\":\"47781282\",\"channelId\":\"10000038\",\"currency\":\"156\",\"amount\":1,\"tradeType\":\"PAY\",\"payStatus\":\"S\",\"notifyStatus\":0,\"orderCreateTime\":\"2021-09-06T05:19:43.000+00:00\",\"orderEfficientTime\":\"2021-09-06T05:19:43.000+00:00\",\"extendField\":null,\"payTime\":\"2021-09-06T05:19:43.000+00:00\",\"remark\":\"\",\"noticeNum\":1,\"sign\":null,\"notifyUrl\":null,\"notifyMode\":\"2\",\"payInfo\":\"1#1#ALIPAY#0#2021090622001432581427657317\",\"lklOrderNo\":\"2021090666210003610012\",\"crdFlg\":\"92\",\"payerId1\":\"2088702852632582\",\"payerId2\":\"rob***@126.com\",\"smCrdFlg\":\"01\",\"tradeTime\":\"20210906131943\",\"accountChannelOrderNo\":\"2021090622001432581427657317\",\"actualPayAmount\":1,\"logNo\":\"66210003610012\"}";

	preSignData := timestamp +"\n" + nonce + "\n" +reqBody + "\n";
	fmt.Println("wangpei test 验证签名1...")
	fmt.Println("params=");fmt.Println(params)
	fmt.Println("wangpei test 验证签名2...")
	fmt.Println("signature="+signature)
	fmt.Println("wangpei test 验证签名3...")
	fmt.Println("Authorization2="+authorization)
	fmt.Println("wangpei test 验证签名4...")
	fmt.Println("preSignData=" + preSignData)
	fmt.Println("wangpei test 验证签名5...")
	//证书 => 公钥
	publicKey := cert.PublicKey.(*rsa.PublicKey)

	//验证签名
	bytes, err := base64.StdEncoding.DecodeString(signature)
	if err != nil {
		fmt.Println("failed to base64.StdEncoding.DecodeString: " + err.Error())
		return err
	}
	hashed := sha256.Sum256([]byte(preSignData))
	err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], bytes)
	if err != nil {
		fmt.Println("failed to VerifyPKCS1v15: " + err.Error())
		return err
	}

	fmt.Println("wangpei test ok")
	return nil
}