package service

import (
	"context"
	"crypto/ecdsa"
	"crypto/ed25519"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"sync"
	"testing"
	"time"

	"github.com/lestrrat-go/jwx/v3/jwa"
	"github.com/lestrrat-go/jwx/v3/jwk"
	"github.com/lestrrat-go/jwx/v3/jwt"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gorm.io/gorm"

	"github.com/pocket-id/pocket-id/backend/internal/common"
	"github.com/pocket-id/pocket-id/backend/internal/model"
	jwkutils "github.com/pocket-id/pocket-id/backend/internal/utils/jwk"
	testutils "github.com/pocket-id/pocket-id/backend/internal/utils/testing"
)

const testEncryptionKey = "0123456789abcdef0123456789abcdef"

const uuidRegexPattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"

func newTestEnvConfig() *common.EnvConfigSchema {
	return &common.EnvConfigSchema{
		AppURL:        "https://test.example.com",
		EncryptionKey: []byte(testEncryptionKey),
	}
}

func initJwtService(t *testing.T, db *gorm.DB, appConfig *AppConfigService, envConfig *common.EnvConfigSchema) *JwtService {
	t.Helper()

	service := &JwtService{}
	err := service.init(t.Context(), db, appConfig, envConfig)
	require.NoError(t, err, "Failed to initialize JWT service")

	return service
}

func setupJwtService(t *testing.T, appConfig *AppConfigService) (*JwtService, *gorm.DB, *common.EnvConfigSchema) {
	t.Helper()

	db := testutils.NewDatabaseForTest(t)
	envConfig := newTestEnvConfig()

	return initJwtService(t, db, appConfig, envConfig), db, envConfig
}

func newTestDbAndEnv(t *testing.T) (*gorm.DB, *common.EnvConfigSchema) {
	t.Helper()

	return testutils.NewDatabaseForTest(t), newTestEnvConfig()
}

func saveKeyToDatabase(t *testing.T, db *gorm.DB, envConfig *common.EnvConfigSchema, appConfig *AppConfigService, key jwk.Key) string {
	t.Helper()

	keyProvider, err := jwkutils.GetKeyProvider(db, envConfig, appConfig.GetDbConfig().InstanceID.Value)
	require.NoError(t, err, "Failed to init key provider")

	err = keyProvider.SaveKey(t.Context(), key)
	require.NoError(t, err, "Failed to save key")

	kid, ok := key.KeyID()
	require.True(t, ok, "Key ID must be set")
	require.NotEmpty(t, kid, "Key ID must not be empty")

	return kid
}

func TestJwtService_Init(t *testing.T) {
	mockConfig := NewTestAppConfigService(&model.AppConfig{
		SessionDuration: model.AppConfigVariable{Value: "60"}, // 60 minutes
	})

	t.Run("should generate new key when none exists", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// Initialize the JWT service
		service := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Verify the private key was set
		require.NotNil(t, service.privateKey, "Private key should be set")

		// Verify the key has been persisted in the database
		keyProvider, err := jwkutils.GetKeyProvider(db, mockEnvConfig, mockConfig.GetDbConfig().InstanceID.Value)
		require.NoError(t, err, "Failed to init key provider")
		key, err := keyProvider.LoadKey(t.Context())
		require.NoError(t, err, "Failed to load key from provider")
		require.NotNil(t, key, "Key should be present in the database")

		// Key should have required properties
		keyID, ok := key.KeyID()
		assert.True(t, ok, "Key should have a key ID")
		assert.NotEmpty(t, keyID)

		keyUsage, ok := key.KeyUsage()
		assert.True(t, ok, "Key should have a key usage")
		assert.Equal(t, KeyUsageSigning, keyUsage)
	})

	t.Run("should load existing JWK key", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// First create a service to generate a key
		firstService := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Get the key ID of the first service
		origKeyID, ok := firstService.privateKey.KeyID()
		require.True(t, ok)

		// Now create a new service that should load the existing key
		secondService := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Verify the loaded key has the same ID as the original
		loadedKeyID, ok := secondService.privateKey.KeyID()
		require.True(t, ok)
		assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")
	})

	t.Run("should load existing JWK for ECDSA keys", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// Create a new JWK and save it to the database
		origKeyID := createECDSAKeyJWK(t, db, mockEnvConfig, mockConfig)

		// Now create a new service that should load the existing key
		svc := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Ensure loaded key has the right algorithm
		alg, ok := svc.privateKey.Algorithm()
		_ = assert.True(t, ok) &&
			assert.Equal(t, jwa.ES256().String(), alg.String(), "Loaded key has the incorrect algorithm")

		// Verify the loaded key has the same ID as the original
		loadedKeyID, ok := svc.privateKey.KeyID()
		_ = assert.True(t, ok) &&
			assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")
	})

	t.Run("should load existing JWK for EdDSA keys", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// Create a new JWK and save it to the database
		origKeyID := createEdDSAKeyJWK(t, db, mockEnvConfig, mockConfig)

		// Now create a new service that should load the existing key
		svc := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Ensure loaded key has the right algorithm and curve
		alg, ok := svc.privateKey.Algorithm()
		_ = assert.True(t, ok) &&
			assert.Equal(t, jwa.EdDSA().String(), alg.String(), "Loaded key has the incorrect algorithm")

		var curve jwa.EllipticCurveAlgorithm
		err := svc.privateKey.Get("crv", &curve)
		_ = assert.NoError(t, err, "Failed to get 'crv' claim") &&
			assert.Equal(t, jwa.Ed25519().String(), curve.String(), "Curve does not match expected value")

		// Verify the loaded key has the same ID as the original
		loadedKeyID, ok := svc.privateKey.KeyID()
		_ = assert.True(t, ok) &&
			assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")
	})

}

func TestJwtService_GetPublicJWK(t *testing.T) {
	mockConfig := NewTestAppConfigService(&model.AppConfig{
		SessionDuration: model.AppConfigVariable{Value: "60"}, // 60 minutes
	})

	t.Run("returns public key when private key is initialized", func(t *testing.T) {
		service, _, _ := setupJwtService(t, mockConfig)

		// Get the JWK (public key)
		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err, "GetPublicJWK should not return an error when private key is initialized")

		// Verify the returned key is valid
		require.NotNil(t, publicKey, "Public key should not be nil")

		// Validate it's actually a public key
		isPrivate, err := jwk.IsPrivateKey(publicKey)
		require.NoError(t, err)
		assert.False(t, isPrivate, "Returned key should be a public key")

		// Check that key has required properties
		keyID, ok := publicKey.KeyID()
		require.True(t, ok, "Public key should have a key ID")
		assert.NotEmpty(t, keyID, "Key ID should not be empty")

		alg, ok := publicKey.Algorithm()
		require.True(t, ok, "Public key should have an algorithm")
		assert.Equal(t, "RS256", alg.String(), "Algorithm should be RS256")
	})

	t.Run("returns public key when ECDSA private key is initialized", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// Create an ECDSA key and save it in the database
		originalKeyID := createECDSAKeyJWK(t, db, mockEnvConfig, mockConfig)

		// Create a JWT service that loads the ECDSA key
		service := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Get the JWK (public key)
		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err, "GetPublicJWK should not return an error when private key is initialized")

		// Verify the returned key is valid
		require.NotNil(t, publicKey, "Public key should not be nil")

		// Validate it's actually a public key
		isPrivate, err := jwk.IsPrivateKey(publicKey)
		require.NoError(t, err)
		assert.False(t, isPrivate, "Returned key should be a public key")

		// Check that key has required properties
		keyID, ok := publicKey.KeyID()
		require.True(t, ok, "Public key should have a key ID")
		assert.Equal(t, originalKeyID, keyID, "Key ID should match the original key ID")

		// Check that the key type is EC
		assert.Equal(t, "EC", publicKey.KeyType().String(), "Key type should be EC")

		// Check that the algorithm is ES256
		alg, ok := publicKey.Algorithm()
		require.True(t, ok, "Public key should have an algorithm")
		assert.Equal(t, "ES256", alg.String(), "Algorithm should be ES256")
	})

	t.Run("returns public key when EdDSA private key is initialized", func(t *testing.T) {
		db := testutils.NewDatabaseForTest(t)
		mockEnvConfig := newTestEnvConfig()

		// Create an EdDSA key and save it in the database
		originalKeyID := createEdDSAKeyJWK(t, db, mockEnvConfig, mockConfig)

		// Create a JWT service that loads the EdDSA key
		service := initJwtService(t, db, mockConfig, mockEnvConfig)

		// Get the JWK (public key)
		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err, "GetPublicJWK should not return an error when private key is initialized")

		// Verify the returned key is valid
		require.NotNil(t, publicKey, "Public key should not be nil")

		// Validate it's actually a public key
		isPrivate, err := jwk.IsPrivateKey(publicKey)
		require.NoError(t, err)
		assert.False(t, isPrivate, "Returned key should be a public key")

		// Check that key has required properties
		keyID, ok := publicKey.KeyID()
		require.True(t, ok, "Public key should have a key ID")
		assert.Equal(t, originalKeyID, keyID, "Key ID should match the original key ID")

		// Check that the key type is OKP
		assert.Equal(t, "OKP", publicKey.KeyType().String(), "Key type should be OKP")

		// Check that the algorithm is EdDSA
		alg, ok := publicKey.Algorithm()
		require.True(t, ok, "Public key should have an algorithm")
		assert.Equal(t, "EdDSA", alg.String(), "Algorithm should be EdDSA")
	})

	t.Run("returns error when private key is not initialized", func(t *testing.T) {
		// Create a service with nil private key
		service := &JwtService{
			privateKey: nil,
		}

		// Try to get the JWK
		publicKey, err := service.GetPublicJWK()

		// Verify it returns an error
		require.Error(t, err, "GetPublicJWK should return an error when private key is nil")
		assert.Contains(t, err.Error(), "key is not initialized", "Error message should indicate key is not initialized")
		assert.Nil(t, publicKey, "Public key should be nil when there's an error")
	})
}

func TestGenerateVerifyAccessToken(t *testing.T) {
	mockConfig := NewTestAppConfigService(&model.AppConfig{
		SessionDuration: model.AppConfigVariable{Value: "60"}, // 60 minutes
	})

	t.Run("generates token for regular user", func(t *testing.T) {
		service, _, _ := setupJwtService(t, mockConfig)

		user := model.User{
			Base:    model.Base{ID: "user123"},
			Email:   new("user@example.com"),
			IsAdmin: false,
		}

		tokenString, err := service.GenerateAccessToken(user, "")
		require.NoError(t, err, "Failed to generate access token")
		assert.NotEmpty(t, tokenString, "Token should not be empty")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token")

		subject, ok := claims.Subject()
		_ = assert.True(t, ok, "User ID not found in token") &&
			assert.Equal(t, user.ID, subject, "Token subject should match user ID")
		isAdmin := false
		if claims.Has(IsAdminClaim) {
			require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim")
		}
		assert.False(t, isAdmin, "isAdmin should be false")
		authenticationMethod, err := service.GetAuthenticationMethod(claims)
		_ = assert.NoError(t, err, "Failed to get amr claim") &&
			assert.Empty(t, authenticationMethod, "amr should be empty when not specified")
		audience, ok := claims.Audience()
		_ = assert.True(t, ok, "Audience not found in token") &&
			assert.Equal(t, []string{service.envConfig.AppURL}, audience, "Audience should contain the app URL")
		jwtID, ok := claims.JwtID()
		_ = assert.True(t, ok, "JWT ID not found in token") &&
			assert.Regexp(t, uuidRegexPattern, jwtID, "JWT ID is not a UUID")

		expectedExp := time.Now().Add(1 * time.Hour)
		expiration, ok := claims.Expiration()
		assert.True(t, ok, "Expiration not found in token")
		timeDiff := expectedExp.Sub(expiration).Minutes()
		assert.InDelta(t, 0, timeDiff, 1.0, "Token should expire in approximately 1 hour")
	})

	t.Run("generates token for admin user", func(t *testing.T) {
		service, _, _ := setupJwtService(t, mockConfig)

		adminUser := model.User{
			Base:    model.Base{ID: "admin123"},
			Email:   new("admin@example.com"),
			IsAdmin: true,
		}

		tokenString, err := service.GenerateAccessToken(adminUser, "")
		require.NoError(t, err, "Failed to generate access token")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token")

		isAdmin := false
		if claims.Has(IsAdminClaim) {
			require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim")
		}
		assert.True(t, isAdmin, "isAdmin should be true")
		subject, ok := claims.Subject()
		_ = assert.True(t, ok, "User ID not found in token") &&
			assert.Equal(t, adminUser.ID, subject, "Token subject should match user ID")
	})

	t.Run("sets authentication method references claim when provided", func(t *testing.T) {
		service, _, _ := setupJwtService(t, mockConfig)

		user := model.User{
			Base: model.Base{ID: "user-with-auth-method"},
		}

		tokenString, err := service.GenerateAccessToken(user, AuthenticationMethodPhishingResistant)
		require.NoError(t, err, "Failed to generate access token")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token")

		authenticationMethod, err := service.GetAuthenticationMethod(claims)
		_ = assert.NoError(t, err, "Failed to get amr claim") &&
			assert.Equal(t, AuthenticationMethodPhishingResistant, authenticationMethod, "amr should match")
	})

	t.Run("uses session duration from config", func(t *testing.T) {
		customMockConfig := NewTestAppConfigService(&model.AppConfig{
			SessionDuration: model.AppConfigVariable{Value: "30"}, // 30 minutes
		})
		service, _, _ := setupJwtService(t, customMockConfig)

		user := model.User{
			Base: model.Base{ID: "user456"},
		}

		tokenString, err := service.GenerateAccessToken(user, "")
		require.NoError(t, err, "Failed to generate access token")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token")

		expectedExp := time.Now().Add(30 * time.Minute)
		expiration, ok := claims.Expiration()
		assert.True(t, ok, "Expiration not found in token")
		timeDiff := expectedExp.Sub(expiration).Minutes()
		assert.InDelta(t, 0, timeDiff, 1.0, "Token should expire in approximately 30 minutes")
	})

	t.Run("works with Ed25519 keys", func(t *testing.T) {
		db, envConfig := newTestDbAndEnv(t)
		origKeyID := createEdDSAKeyJWK(t, db, envConfig, mockConfig)
		service := initJwtService(t, db, mockConfig, envConfig)

		loadedKeyID, ok := service.privateKey.KeyID()
		require.True(t, ok)
		assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")

		user := model.User{
			Base:    model.Base{ID: "eddsauser123"},
			Email:   new("eddsauser@example.com"),
			IsAdmin: true,
		}

		tokenString, err := service.GenerateAccessToken(user, "")
		require.NoError(t, err, "Failed to generate access token with Ed25519 key")
		assert.NotEmpty(t, tokenString, "Token should not be empty")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token with Ed25519 key")

		subject, ok := claims.Subject()
		_ = assert.True(t, ok, "User ID not found in token") &&
			assert.Equal(t, user.ID, subject, "Token subject should match user ID")
		isAdmin := false
		if claims.Has(IsAdminClaim) {
			require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim")
		}
		assert.True(t, isAdmin, "isAdmin should be true")

		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err)
		assert.Equal(t, "OKP", publicKey.KeyType().String(), "Key type should be OKP")
		alg, ok := publicKey.Algorithm()
		require.True(t, ok)
		assert.Equal(t, "EdDSA", alg.String(), "Algorithm should be EdDSA")
	})

	t.Run("works with P-256 keys", func(t *testing.T) {
		db, envConfig := newTestDbAndEnv(t)
		origKeyID := createECDSAKeyJWK(t, db, envConfig, mockConfig)
		service := initJwtService(t, db, mockConfig, envConfig)

		loadedKeyID, ok := service.privateKey.KeyID()
		require.True(t, ok)
		assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")

		user := model.User{
			Base:    model.Base{ID: "ecdsauser123"},
			Email:   new("ecdsauser@example.com"),
			IsAdmin: true,
		}

		tokenString, err := service.GenerateAccessToken(user, "")
		require.NoError(t, err, "Failed to generate access token with ECDSA key")
		assert.NotEmpty(t, tokenString, "Token should not be empty")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token with ECDSA key")

		subject, ok := claims.Subject()
		_ = assert.True(t, ok, "User ID not found in token") &&
			assert.Equal(t, user.ID, subject, "Token subject should match user ID")
		isAdmin := false
		if claims.Has(IsAdminClaim) {
			require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim")
		}
		assert.True(t, isAdmin, "isAdmin should be true")

		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err)
		assert.Equal(t, "EC", publicKey.KeyType().String(), "Key type should be EC")
		alg, ok := publicKey.Algorithm()
		require.True(t, ok)
		assert.Equal(t, "ES256", alg.String(), "Algorithm should be ES256")
	})

	t.Run("works with RSA-4096 keys", func(t *testing.T) {
		db, envConfig := newTestDbAndEnv(t)
		origKeyID := createRSA4096KeyJWK(t, db, envConfig, mockConfig)
		service := initJwtService(t, db, mockConfig, envConfig)

		loadedKeyID, ok := service.privateKey.KeyID()
		require.True(t, ok)
		assert.Equal(t, origKeyID, loadedKeyID, "Loaded key should have the same ID as the original")

		user := model.User{
			Base:    model.Base{ID: "rsauser123"},
			Email:   new("rsauser@example.com"),
			IsAdmin: true,
		}

		tokenString, err := service.GenerateAccessToken(user, "")
		require.NoError(t, err, "Failed to generate access token with RSA key")
		assert.NotEmpty(t, tokenString, "Token should not be empty")

		claims, err := service.VerifyAccessToken(tokenString)
		require.NoError(t, err, "Failed to verify generated token with RSA key")

		subject, ok := claims.Subject()
		_ = assert.True(t, ok, "User ID not found in token") &&
			assert.Equal(t, user.ID, subject, "Token subject should match user ID")
		isAdmin := false
		if claims.Has(IsAdminClaim) {
			require.NoError(t, claims.Get(IsAdminClaim, &isAdmin), "Failed to get isAdmin claim")
		}
		assert.True(t, isAdmin, "isAdmin should be true")

		publicKey, err := service.GetPublicJWK()
		require.NoError(t, err)
		assert.Equal(t, jwa.RSA().String(), publicKey.KeyType().String(), "Key type should be RSA")
		alg, ok := publicKey.Algorithm()
		require.True(t, ok)
		assert.Equal(t, jwa.RS256().String(), alg.String(), "Algorithm should be RS256")
	})
}

func TestTokenTypeValidator(t *testing.T) {
	// Create a context for the validator function
	ctx := context.Background()

	t.Run("succeeds when token type matches expected type", func(t *testing.T) {
		// Create a token with the expected type
		token := jwt.New()
		err := token.Set(TokenTypeClaim, AccessTokenJWTType)
		require.NoError(t, err, "Failed to set token type claim")

		// Create a validator function for the expected type
		validator := TokenTypeValidator(AccessTokenJWTType)

		// Validate the token
		err = validator(ctx, token)
		assert.NoError(t, err, "Validator should accept token with matching type")
	})

	t.Run("fails when token type doesn't match expected type", func(t *testing.T) {
		// Create a token with a different type
		token := jwt.New()
		err := token.Set(TokenTypeClaim, "other-token")
		require.NoError(t, err, "Failed to set token type claim")

		// Create a validator function for a different expected type
		validator := TokenTypeValidator(AccessTokenJWTType)

		// Validate the token
		err = validator(ctx, token)
		require.Error(t, err, "Validator should reject token with non-matching type")
		assert.Contains(t, err.Error(), "invalid token type: expected access-token, got other-token")
	})

	t.Run("fails when token type claim is missing", func(t *testing.T) {
		// Create a token without a type claim
		token := jwt.New()

		// Create a validator function
		validator := TokenTypeValidator(AccessTokenJWTType)

		// Validate the token
		err := validator(ctx, token)
		require.Error(t, err, "Validator should reject token without type claim")
		assert.Contains(t, err.Error(), "failed to get token type claim")
	})
}

func importKey(t *testing.T, db *gorm.DB, envConfig *common.EnvConfigSchema, appConfig *AppConfigService, privateKeyRaw any) string {
	t.Helper()

	privateKey, err := jwkutils.ImportRawKey(privateKeyRaw, "", "")
	require.NoError(t, err, "Failed to import private key")

	return saveKeyToDatabase(t, db, envConfig, appConfig, privateKey)
}

// Because generating a RSA-406 key isn't immediate, we pre-compute one
var (
	rsaKeyPrecomputed    *rsa.PrivateKey
	rsaKeyPrecomputeOnce sync.Once
)

func createRSA4096KeyJWK(t *testing.T, db *gorm.DB, envConfig *common.EnvConfigSchema, appConfig *AppConfigService) string {
	t.Helper()

	rsaKeyPrecomputeOnce.Do(func() {
		var err error
		rsaKeyPrecomputed, err = rsa.GenerateKey(rand.Reader, 4096)
		if err != nil {
			panic("failed to precompute RSA key: " + err.Error())
		}
	})

	// Import as JWK and save it
	return importKey(t, db, envConfig, appConfig, rsaKeyPrecomputed)
}

func createECDSAKeyJWK(t *testing.T, db *gorm.DB, envConfig *common.EnvConfigSchema, appConfig *AppConfigService) string {
	t.Helper()

	// Generate a new P-256 ECDSA key
	privateKeyRaw, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	require.NoError(t, err, "Failed to generate ECDSA key")

	// Import as JWK and save it
	return importKey(t, db, envConfig, appConfig, privateKeyRaw)
}

// Helper function to create an Ed25519 key and save it as JWK
func createEdDSAKeyJWK(t *testing.T, db *gorm.DB, envConfig *common.EnvConfigSchema, appConfig *AppConfigService) string {
	t.Helper()

	// Generate a new Ed25519 key pair
	_, privateKeyRaw, err := ed25519.GenerateKey(rand.Reader)
	require.NoError(t, err, "Failed to generate Ed25519 key")

	// Import as JWK and save it
	return importKey(t, db, envConfig, appConfig, privateKeyRaw)
}
