package util

import (
	"ARKItems/configs"
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"math/big"
	"time"
)

const (
	SECRETKEY = "996icu12345611" //私钥
)

type CustomClaims struct {
	UserId int64
	jwt.StandardClaims
}

func GetJsonAnyParam(c *gin.Context) func(param string) (interface{}, error) {
	jsonData := map[string]interface{}{}
	err := c.BindJSON(&jsonData)

	return func(param string) (interface{}, error) {
		if err != nil {
			return nil, err
		}
		value, err := func() (interface{}, error) {

			i, exists := jsonData[param]
			if !exists {
				return nil, errors.New("缺少" + param + "字段")
			}

			return i, nil
		}()
		if err != nil {
			return nil, err
		}
		return value, err
	}
}

func GenerateToken(userId string) (string, error) {
	maxAge := 60 * 60 * 24
	// Create the Claims
	claims := &jwt.StandardClaims{
		ExpiresAt: time.Now().Add(time.Duration(maxAge) * time.Second).Unix(), // 过期时间，必须设置,
		Issuer:    userId,                                                     // 非必须，也可以填充用户名，
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(SECRETKEY))
	if err != nil {
		fmt.Println(err)
	}
	return tokenString, err
}

func ParseToken(tokenString string) (jwt.MapClaims, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}

		// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
		return []byte(SECRETKEY), nil
	})
	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		return claims, nil
	} else {
		return nil, err
	}
}

func JudgmentUserInfo(info jwt.MapClaims) bool {
	i, ok := info["iss"].(string)
	if ok {
		return i == configs.Manager.Username
	}
	return false
}

func RandomInt(min, max *big.Int) *big.Int {
	// 读取密码学安全的随机比特
	byteLen := (max.BitLen() + 7) / 8
	b := make([]byte, byteLen)
	rand.Read(b)

	// 将字节转换为大整数
	r := new(big.Int).SetBytes(b)

	// 需要将生成的大整数范围限制在[min,max]
	r.Rem(r, new(big.Int).Sub(max, min)).Add(r, min)
	return r
}

// DataToObject json转对象
func DataToObject(data interface{}, obj interface{}) error {
	marshal, err := json.Marshal(data)
	if err != nil {
		return err
	}
	return json.Unmarshal(marshal, obj)
}
func DataToMap(data interface{}) map[string]interface{} {
	marshal, err := json.Marshal(data)
	if err != nil {
		fmt.Println(err)
	}
	var obj map[string]interface{}
	json.Unmarshal(marshal, &obj)
	return obj
}
