/// Synor Crypto SDK Examples for Flutter/Dart
///
/// Demonstrates quantum-resistant cryptographic operations:
/// - Hybrid Ed25519 + Dilithium3 signatures
/// - BIP-39 mnemonic generation and validation
/// - Post-quantum algorithms (Falcon, SPHINCS+)
/// - Key derivation functions
library;

import 'dart:io';
import 'package:synor_crypto/synor_crypto.dart';

Future<void> main() async {
  // Initialize client
  final config = CryptoConfig(
    apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key',
    endpoint: 'https://crypto.synor.io/v1',
    timeout: const Duration(seconds: 30),
    retries: 3,
    debug: false,
    defaultNetwork: Network.mainnet,
  );

  final crypto = SynorCrypto(config);

  try {
    // Check service health
    final healthy = await crypto.healthCheck();
    print('Service healthy: $healthy\n');

    // Run examples
    await mnemonicExample(crypto);
    await keypairExample(crypto);
    await signingExample(crypto);
    await falconExample(crypto);
    await sphincsExample(crypto);
    await kdfExample(crypto);
    await hashExample(crypto);
  } finally {
    await crypto.close();
  }
}

Future<void> mnemonicExample(SynorCrypto crypto) async {
  print('=== Mnemonic Operations ===');

  // Generate a 24-word mnemonic (256-bit entropy)
  final mnemonic = await crypto.mnemonic.generate(24);
  print('Generated mnemonic: ${mnemonic.phrase}');
  print('Word count: ${mnemonic.wordCount}');

  // Validate a mnemonic
  final validation = await crypto.mnemonic.validate(mnemonic.phrase);
  print('Valid: ${validation.valid}');
  if (!validation.valid) {
    print('Error: ${validation.error}');
  }

  // Convert mnemonic to seed
  final seed = await crypto.mnemonic.toSeed(
    mnemonic.phrase,
    passphrase: 'optional-passphrase',
  );
  print('Seed (hex): ${seed.toHex().substring(0, 32)}...');

  // Word suggestions for autocomplete
  final suggestions = await crypto.mnemonic.suggestWords('aban', limit: 5);
  print('Suggestions for "aban": ${suggestions.join(", ")}');

  print('');
}

Future<void> keypairExample(SynorCrypto crypto) async {
  print('=== Keypair Operations ===');

  // Generate a random keypair
  final keypair = await crypto.keypairs.generate();
  print('Generated hybrid keypair:');
  print('  Ed25519 public key size: ${keypair.publicKey.ed25519Bytes.length} bytes');
  print('  Dilithium public key size: ${keypair.publicKey.dilithiumBytes.length} bytes');
  print('  Total public key size: ${keypair.publicKey.size} bytes');

  // Get addresses for different networks
  print('\nAddresses:');
  print('  Mainnet: ${keypair.getAddress(Network.mainnet)}');
  print('  Testnet: ${keypair.getAddress(Network.testnet)}');
  print('  Devnet: ${keypair.getAddress(Network.devnet)}');

  // Create keypair from mnemonic (deterministic)
  final mnemonic = await crypto.mnemonic.generate(24);
  final keypair2 = await crypto.keypairs.fromMnemonic(mnemonic.phrase, '');
  final addr = keypair2.getAddress(Network.mainnet);
  print('\nKeypair from mnemonic: ${addr.substring(0, 20)}...');

  // Derive child keypair using BIP-44 path
  final path = DerivationPath.external(0, 0); // m/44'/21337'/0'/0/0
  print('Derivation path: $path');

  print('');
}

Future<void> signingExample(SynorCrypto crypto) async {
  print('=== Hybrid Signing ===');

  // Generate keypair
  final keypair = await crypto.keypairs.generate();

  // Sign a message
  final message = 'Hello, quantum-resistant world!'.codeUnits;
  final signature = await crypto.signing.sign(keypair, message);

  print('Signature created:');
  print('  Ed25519 component: ${signature.ed25519Bytes.length} bytes');
  print('  Dilithium component: ${signature.dilithiumBytes.length} bytes');
  print('  Total signature size: ${signature.size} bytes');

  // Verify the signature
  final valid = await crypto.signing.verify(keypair.publicKey, message, signature);
  print('\nVerification result: $valid');

  // Verify with tampered message fails
  final tamperedMessage = 'Hello, tampered message!'.codeUnits;
  final invalidResult = await crypto.signing.verify(
    keypair.publicKey,
    tamperedMessage,
    signature,
  );
  print('Tampered message verification: $invalidResult');

  print('');
}

Future<void> falconExample(SynorCrypto crypto) async {
  print('=== Falcon Post-Quantum Signatures ===');

  // Generate Falcon-512 keypair (128-bit security)
  final falcon512 = await crypto.falcon.generate(FalconVariant.falcon512);
  print('Falcon-512 keypair:');
  print('  Public key: ${falcon512.publicKey.keyBytes.length} bytes');
  print('  Security level: 128-bit');

  // Generate Falcon-1024 keypair (256-bit security)
  final falcon1024 = await crypto.falcon.generate(FalconVariant.falcon1024);
  print('\nFalcon-1024 keypair:');
  print('  Public key: ${falcon1024.publicKey.keyBytes.length} bytes');
  print('  Security level: 256-bit');

  // Sign with Falcon-512
  final message = 'Post-quantum secure message'.codeUnits;
  final signature = await crypto.falcon.sign(falcon512, message);
  print('\nFalcon-512 signature: ${signature.signatureBytes.length} bytes');

  // Verify
  final valid = await crypto.falcon.verify(
    falcon512.publicKey.keyBytes,
    message,
    signature,
  );
  print('Verification: $valid');

  print('');
}

Future<void> sphincsExample(SynorCrypto crypto) async {
  print('=== SPHINCS+ Hash-Based Signatures ===');

  // SPHINCS+ variants with different security levels
  final variants = [
    (SphincsVariant.shake128s, 128, 7856),
    (SphincsVariant.shake192s, 192, 16224),
    (SphincsVariant.shake256s, 256, 29792),
  ];

  // Generate and demonstrate each variant
  for (final (variant, security, sigSize) in variants) {
    final keypair = await crypto.sphincs.generate(variant);
    print('SPHINCS+ $variant:');
    print('  Security level: $security-bit');
    print('  Expected signature size: $sigSize bytes');

    // Sign a message
    final message = 'Hash-based quantum security'.codeUnits;
    final signature = await crypto.sphincs.sign(keypair, message);
    print('  Actual signature size: ${signature.signatureBytes.length} bytes');

    // Verify
    final valid = await crypto.sphincs.verify(
      keypair.publicKey.keyBytes,
      message,
      signature,
    );
    print('  Verification: $valid\n');
  }
}

Future<void> kdfExample(SynorCrypto crypto) async {
  print('=== Key Derivation Functions ===');

  // HKDF (HMAC-based Key Derivation Function)
  final seed = 'master-secret-key-material-here'.codeUnits;
  final hkdfConfig = DerivationConfig(
    salt: 'application-salt'.codeUnits,
    info: 'encryption-key'.codeUnits,
    outputLength: 32,
  );

  final derivedKey = await crypto.kdf.deriveKey(seed, hkdfConfig);
  print('HKDF derived key: ${derivedKey.toHex()}');

  // PBKDF2 (Password-Based Key Derivation Function)
  final password = 'user-password'.codeUnits;
  final pbkdf2Config = PasswordDerivationConfig(
    salt: 'random-salt-value'.codeUnits,
    iterations: 100000,
    outputLength: 32,
  );

  final passwordKey = await crypto.kdf.deriveFromPassword(password, pbkdf2Config);
  print('PBKDF2 derived key: ${passwordKey.toHex()}');

  print('');
}

Future<void> hashExample(SynorCrypto crypto) async {
  print('=== Hash Functions ===');

  final data = 'Data to hash'.codeUnits;

  // SHA3-256 (FIPS 202)
  final sha3 = await crypto.hash.sha3_256(data);
  print('SHA3-256: ${sha3.hex}');

  // BLAKE3 (fast, parallel)
  final blake3 = await crypto.hash.blake3(data);
  print('BLAKE3:   ${blake3.hex}');

  // Keccak-256 (Ethereum compatible)
  final keccak = await crypto.hash.keccak256(data);
  print('Keccak:   ${keccak.hex}');

  print('');
}

extension on List<int> {
  String toHex() {
    return map((b) => b.toRadixString(16).padLeft(2, '0')).join();
  }
}
