package crypto

// KeyResolver decrypts API keys using the appropriate tier:
//   - global/team → env-derived key
//   - personal    → user's UEK from cache
type KeyResolver struct {
	envKey   []byte // derived from ENCRYPTION_KEY
	uekCache *UEKCache
}

// NewKeyResolver creates a resolver. envKey may be nil if ENCRYPTION_KEY is
// not set (fresh install with no providers — decryption will fail gracefully).
func NewKeyResolver(envKey []byte, cache *UEKCache) *KeyResolver {
	return &KeyResolver{envKey: envKey, uekCache: cache}
}

// Decrypt resolves an API key given its encrypted form, nonce, scope, and
// the requesting user's ID (needed for personal-scope keys).
func (r *KeyResolver) Decrypt(ciphertext, nonce []byte, keyScope, userID string) (string, error) {
	if len(ciphertext) == 0 {
		return "", nil // No key stored
	}

	switch keyScope {
	case "global", "team":
		if r.envKey == nil {
			return "", ErrNoEncryptionKey
		}
		return Decrypt(ciphertext, nonce, r.envKey)

	case "personal":
		uek, ok := r.uekCache.Load(userID)
		if !ok {
			return "", ErrVaultLocked
		}
		return Decrypt(ciphertext, nonce, uek)

	default:
		// Fallback: try env key (covers pre-migration or unknown scopes)
		if r.envKey == nil {
			return "", ErrNoEncryptionKey
		}
		return Decrypt(ciphertext, nonce, r.envKey)
	}
}

// EncryptForScope encrypts an API key with the appropriate key for the scope.
func (r *KeyResolver) EncryptForScope(plaintext, keyScope, userID string) ([]byte, []byte, error) {
	if plaintext == "" {
		return nil, nil, nil
	}

	switch keyScope {
	case "personal":
		uek, ok := r.uekCache.Load(userID)
		if !ok {
			return nil, nil, ErrVaultLocked
		}
		return Encrypt(plaintext, uek)

	default: // global, team
		if r.envKey == nil {
			return nil, nil, ErrNoEncryptionKey
		}
		return Encrypt(plaintext, r.envKey)
	}
}

// HasEnvKey returns true if the platform encryption key is available.
func (r *KeyResolver) HasEnvKey() bool {
	return r.envKey != nil
}
