package jwt

import (
	"errors"
	"time"

	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/jwt_utils"
	sbytes "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/security/securebytes"
)

// JWTProvider provides interface for abstracting JWT generation.
type JWTProvider interface {
	GenerateJWTToken(uuid string, ad time.Duration) (string, time.Time, error)
	GenerateJWTTokenPair(uuid string, ad time.Duration, rd time.Duration) (string, time.Time, string, time.Time, error)
	ProcessJWTToken(reqToken string) (string, error)
}

type jwtProvider struct {
	hmacSecret *sbytes.SecureBytes
}

// NewProvider Constructor that returns the JWT generator.
func NewJWTProvider(cfg *config.Configuration) JWTProvider {
	// Convert JWT secret string to SecureBytes
	secret, _ := sbytes.NewSecureBytes([]byte(cfg.JWT.Secret))
	return jwtProvider{
		hmacSecret: secret,
	}
}

// GenerateJWTToken generates a single JWT token.
func (p jwtProvider) GenerateJWTToken(uuid string, ad time.Duration) (string, time.Time, error) {
	return jwt_utils.GenerateJWTToken(p.hmacSecret.Bytes(), uuid, ad)
}

// GenerateJWTTokenPair Generate the `access token` and `refresh token` for the secret key.
func (p jwtProvider) GenerateJWTTokenPair(uuid string, ad time.Duration, rd time.Duration) (string, time.Time, string, time.Time, error) {
	return jwt_utils.GenerateJWTTokenPair(p.hmacSecret.Bytes(), uuid, ad, rd)
}

func (p jwtProvider) ProcessJWTToken(reqToken string) (string, error) {
	if p.hmacSecret == nil {
		return "", errors.New("HMAC secret is required")
	}
	return jwt_utils.ProcessJWTToken(p.hmacSecret.Bytes(), reqToken)
}
