package controllers

import (
	"fmt"
	"github.com/golang-jwt/jwt"
	//"github.com/dgrijalva/jwt-go"
	"time"
)

const (
	ExpireDuration = 3600 * time.Second
	accessKey      = "next658bddfdd8b829226f1387ec"               // NextHuman平台accessKey
	accessSecret   = "w4iaxcax1n1PfyaDVd_HEY8PysVsOOAkmGJisqDwlW" // NextHuman平台 accessSecret
)

type CustomClaims struct {
	jwt.StandardClaims
	Role      string `json:"role"`
	Timestamp int64  `json:"timestamp"`
}

// 生成token
func GenerateToken() (string, error) {
	// 定义token的过期时间
	expireTime := time.Now().Add(ExpireDuration).Unix() //过期时间为秒
	fmt.Println("expireTime: ", expireTime)
	// 创建一个自定义的Claims
	claims := &CustomClaims{
		Role:      "role.visit",
		Timestamp: time.Now().UnixMilli(), // 当前时间戳毫秒级
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime,
		},
	}

	// 使用 JWT 签名算法生成token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 将token进行加盐加密
	// 注意：该方法参数虽然是interface{}，但是必须传入[]byte类型的参数
	tokenString, err := token.SignedString([]byte(accessSecret))
	if err != nil {
		return "", err
	}

	return accessKey + "@" + tokenString, nil

}

func ParseToken(tokenString string) (*CustomClaims, error) {
	// 解析 token
	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		// 注意：虽然返回值是interface，但是这里必须返回[]byte类型，否则运行时会报错key is of invalid type
		return []byte(accessSecret), nil
	})
	if err != nil {
		return nil, err
	}

	if myClaims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
		return myClaims, nil
	} else {
		return nil, jwt.NewValidationError("invalid token", jwt.ValidationErrorClaimsInvalid)
	}
}

func GenerateToken1() (string, error) {
	// 创建 JWT 的头部
	token := jwt.New(jwt.SigningMethodHS256)

	// 设置 JWT 的负载（Payload）
	claims := token.Claims.(jwt.MapClaims)
	claims["aud"] = "app"                                   // 接收者
	claims["iss"] = accessKey                               // 签发者
	claims["exp"] = time.Now().Add(10 * time.Minute).Unix() // 过期时间
	claims["iat"] = time.Now().Unix()                       // 签发时间

	// 使用 accessSecret 来签名并生成最终的 Token
	tokenString, err := token.SignedString([]byte(accessSecret))
	if err != nil {
		return "", err
	}

	return tokenString, nil
}

// CreateAccessToken 创建访问令牌
func CreateAccessToken1() (string, error) {
	// 创建JWT令牌
	token := jwt.New(jwt.SigningMethodHS256)
	// 设置JWT声明
	claims := token.Claims.(jwt.MapClaims)
	claims["role"] = "role.visit"
	claims["timestamp"] = time.Now().Unix()
	fmt.Println(time.Now().UnixMilli())

	claims["exp"] = time.Now().UnixMilli() + 30*60*1000 // 设置30分钟后过期

	// 使用accessSecret签名并获得完整的编码后的字符串令牌
	tokenString, err := token.SignedString([]byte(accessSecret))
	if err != nil {
		return "", err
	}

	return accessKey + "@" + tokenString, nil
}

func CreateAccessToken2() (string, error) {
	// 设置我们自己的自定义和标准JWT声明
	claims := &CustomClaims{
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(6 * time.Hour).Unix(), // Token过期时间设置为24小时后
		},
		Role:      "role.visit",
		Timestamp: time.Now().Unix(), // 当前时间戳秒级
	}

	// 创建一个新的令牌，指定签名方法和声明
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// 使用accessSecret作为HMAC密钥来签名
	signedToken, err := token.SignedString([]byte(accessSecret))
	if err != nil {
		return "", err
	}

	return accessKey + "@" + signedToken, nil
}
