package security

import (
	"errors"
	"time"

	"github.com/golang-jwt/jwt/v5"
)

type WebClaims struct {
	UserID         string `json:"user_id"`
	UID            string `json:"uid"`
	Username       string `json:"username"`
	SessionVersion int64  `json:"session_version"`
	TokenType      string `json:"token_type"`
	jwt.RegisteredClaims
}

type WebTokenService struct {
	Secret    []byte
	AccessTTL time.Duration
}

func (s WebTokenService) NewAccessToken(userID, uid, username string, sessionVersion int64) (string, time.Time, error) {
	now := time.Now()
	expires := now.Add(s.AccessTTL)
	claims := WebClaims{
		UserID: userID, UID: uid, Username: username, SessionVersion: sessionVersion, TokenType: "web_access",
		RegisteredClaims: jwt.RegisteredClaims{Subject: userID, IssuedAt: jwt.NewNumericDate(now), ExpiresAt: jwt.NewNumericDate(expires)},
	}
	token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(s.Secret)
	return token, expires, err
}

func (s WebTokenService) ParseAccessToken(raw string) (*WebClaims, error) {
	claims := new(WebClaims)
	token, err := jwt.ParseWithClaims(raw, claims, func(token *jwt.Token) (any, error) {
		if token.Method != jwt.SigningMethodHS256 {
			return nil, errors.New("不支持的签名算法")
		}
		return s.Secret, nil
	})
	if err != nil || !token.Valid || claims.TokenType != "web_access" {
		return nil, errors.New("登录凭证无效或已过期")
	}
	return claims, nil
}
