import Foundation

enum DatabaseEncryptionKeyError: Error {
    case keyNotAvailable
}

final class DatabaseEncryptionKeyManager {
    static let shared = DatabaseEncryptionKeyManager()

    private let keychainService: KeychainService
    private let serviceName = "yobble.database.encryption"
    private let accountName = "sqlcipher_key"
    /// Hardcoded dev key used until the user saves their own password-derived key.
    private let fallbackKey: String

    init(
        keychainService: KeychainService = .shared,
        fallbackKey: String = AppConfig.DEFAULT_DATABASE_ENCRYPTION_KEY
    ) {
        self.keychainService = keychainService
        self.fallbackKey = fallbackKey
    }

    func currentKey() throws -> String {
        if let key = keychainService.get(forKey: accountName, service: serviceName), !key.isEmpty {
            return key
        }
        guard !fallbackKey.isEmpty else {
            throw DatabaseEncryptionKeyError.keyNotAvailable
        }
        return fallbackKey
    }

    func persistKey(_ key: String) {
        keychainService.save(key, forKey: accountName, service: serviceName)
    }

    func clearPersistedKey() {
        keychainService.delete(forKey: accountName, service: serviceName)
    }

    func hasPersistedKey() -> Bool {
        keychainService.get(forKey: accountName, service: serviceName) != nil
    }
}
