package asign

import (
	"crypto"
	"crypto/md5"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/hex"
	"encoding/pem"
	"errors"
	"fmt"
	"strconv"
	"time"
)

// 签名规范：
//
//	1、表单提交方式：form-data
//	2、请求头部参数
//	    参数1：sign（签名值，具体算法参考一下的前面算法）
//	    参数2：timestamp（时间戳，13位）
//	3、请求体参数：
//	    参数1：appId（appId值，每个接入者唯一一个）
//	    参数2：timestamp（时间戳，13位，与上述一致）
//	    参数3：bizData（json字符串，举个例子，比方说要传合同编号如：{"contractNo":"0001"}）
//	4、签名算法：
//	    4.1、将上述3所属的bizData（json字符串），按照阿拉伯字母排序(如：{"ba":1,"ac":2}--->{"ac":2,"ba":1})，
//	    4.2、将4.1排序后的字符串，将【bizData+md5（bizData）+ appId + timestatmp】拼接后利用RSA非对称加密算法（SHA1withRSA），计算出最后的签名sign，对其base64编码，放入head的key（sign）中。
func GetSignature(bizData string, appId string, privateKeyPEM string) (signatureBase64 string, timestamp string, err error) {
	timestamp = strconv.FormatInt(time.Now().UnixMilli(), 10)
	// Parse the privateKeyPEM into an RSA private key
	privateKeyBlock, _ := pem.Decode([]byte(privateKeyPEM))
	if privateKeyBlock == nil || privateKeyBlock.Type != "RSA PRIVATE KEY" {
		err = errors.New("签名失败: Error decoding private key PEM")
		return
	}
	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
	if err != nil {
		return
	}

	// md5（bizData）
	m := md5.New()
	m.Write([]byte(bizData))
	bdMd5Hx := hex.EncodeToString(m.Sum(nil))

	// Message to be signed
	message := bizData + bdMd5Hx + appId + timestamp

	// Sign the message using SHA1withRSA
	signature, err := signMessage(message, privateKey)
	if err != nil {
		fmt.Println("Error signing the message:", err)
		return
	}
	fmt.Println(signature)

	return
}

// signMessage signs the given message using SHA1withRSA
func signMessage(message string, privateKey *rsa.PrivateKey) ([]byte, error) {
	hashed := sha1.Sum([]byte(message))
	return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, hashed[:])
}

// verifySignature verifies the given signature for the message using SHA1withRSA
// func verifySignature(message string, signature []byte, publicKey *rsa.PublicKey) bool {
// 	hashed := sha1.Sum([]byte(message))
// 	err := rsa.VerifyPKCS1v15(publicKey, crypto.SHA1, hashed[:], signature)
// 	return err == nil
// }
