import 'package:commons_core/commons_core.dart';

import 'secret_store.dart';

/// Owns the app's secrets in the OS keystore and creates them on first run:
///
/// - the **DB key**: a random 256-bit symmetric key for SQLCipher (NOT derived
///   from any user password — see CLAUDE.md identity section);
/// - the **root seed**: the Duniter/Ğ1-style identity seed (stub for now).
///
/// Both are stored as lowercase hex strings.
class SecureKeyStore {
  SecureKeyStore({required SecretStore store, IdentityService? identity})
    : _store = store,
      _identity = identity ?? IdentityService();

  final SecretStore _store;
  final IdentityService _identity;

  static const dbKeyName = 'tane.db_key';
  static const rootSeedName = 'tane.root_seed';
  static const _dbKeyLengthBytes = 32;

  /// The SQLCipher database key as hex, created and persisted on first access.
  Future<String> databaseKeyHex() =>
      _readOrCreate(dbKeyName, () => randomBytes(_dbKeyLengthBytes));

  /// The root identity seed as hex, created and persisted on first access.
  Future<String> rootSeedHex() =>
      _readOrCreate(rootSeedName, _identity.generateRootSeed);

  /// Replaces the root seed with one recovered from a printed code (restoring
  /// your bank on a new device recovers your identity too). The DB key is
  /// untouched — it never leaves this device's keystore.
  Future<void> adoptRootSeed(String seedHex) =>
      _store.write(rootSeedName, seedHex);

  Future<String> _readOrCreate(
    String key,
    List<int> Function() generate,
  ) async {
    final existing = await _store.read(key);
    if (existing != null) return existing;
    final hex = _toHex(generate());
    await _store.write(key, hex);
    return hex;
  }

  static String _toHex(List<int> bytes) =>
      bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
}
