package utils

import (
	"context"
	"errors"
	"github.com/golang-jwt/jwt/v5"
	"google.golang.org/grpc/metadata"
	"strconv"
	"time"
)

type Claims struct {
	USN int64 `json:"usn"`
	jwt.RegisteredClaims
}

func GenToken(usn int64, secret string, expires time.Duration) (string, error) {
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, Claims{
		USN: usn,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(expires)),
		},
	})
	return token.SignedString([]byte(secret))
}

func ParseToken(tokenString string, secret string) (*Claims, error) {
	if tokenString == "" {
		return nil, errors.New("invalid token")
	}
	claims := &Claims{}
	token, err := jwt.ParseWithClaims(tokenString, claims, func(_ *jwt.Token) (interface{}, error) {
		return []byte(secret), nil
	})
	if err != nil {
		return nil, err
	}
	if !token.Valid {
		return nil, errors.New("invalid token")
	}
	return claims, nil
}

func ShouldBindUsn(ctx context.Context, usn *int64) bool {
	if md, ok := metadata.FromIncomingContext(ctx); ok {
		usnArr := md.Get("X-Usn")
		if len(usnArr) == 0 || usnArr[0] == "" {
			return false
		}
		s, _ := strconv.Atoi(usnArr[0])
		if s > 0 {
			*usn = int64(s)
		}
	}
	return *usn > 0
}
