package union_pay

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
)

func Sign(data string, privateKeyPEM []byte) (string, error) {
	block, _ := pem.Decode(privateKeyPEM)
	if block == nil {
		return "", errors.New("failed to parse PEM block containing the private key")
	}

	privyKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", fmt.Errorf("failed to parse DER encoded private key: %v", err)
	}

	hashed := sha256.Sum256([]byte(data))
	signature, err := rsa.SignPKCS1v15(rand.Reader, privyKey, crypto.SHA256, hashed[:])
	if err != nil {
		return "", fmt.Errorf("failed to sign: %v", err)
	}

	return base64.StdEncoding.EncodeToString(signature), nil
}

func Verify(data, signature string, publicKeyPEM []byte) bool {
	block, _ := pem.Decode(publicKeyPEM)
	if block == nil {
		fmt.Println("failed to parse PEM block containing the public key")
		return false
	}

	pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		fmt.Println("error parsing public key:", err)
		return false
	}

	rsaPubKey, ok := pubKey.(*rsa.PublicKey)
	if !ok {
		fmt.Println("not an RSA public key")
		return false
	}

	hashed := sha256.Sum256([]byte(data))
	sig, err := base64.StdEncoding.DecodeString(signature)
	if err != nil {
		fmt.Println("error decoding signature:", err)
		return false
	}

	err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.SHA256, hashed[:], sig)
	if err != nil {
		fmt.Println("signature verification error:", err)
		return false
	}

	return true
}