/**
 * Synor Crypto SDK Types
 *
 * Quantum-resistant cryptographic primitives for the Synor blockchain.
 */

// ============================================================================
// Enumerations
// ============================================================================

/** Network type for address generation */
export type Network = 'mainnet' | 'testnet' | 'devnet';

/** Supported mnemonic word counts */
export type MnemonicWordCount = 12 | 15 | 18 | 21 | 24;

/** Falcon variant selection */
export type FalconVariant = 'falcon512' | 'falcon1024';

/** SPHINCS+ variant selection */
export type SphincsVariant = 'shake128s' | 'shake192s' | 'shake256s';

/** Post-quantum algorithm family */
export type PqAlgorithm = 'dilithium3' | 'falcon512' | 'falcon1024' | 'sphincs128s' | 'sphincs192s' | 'sphincs256s';

/** Algorithm family */
export type AlgorithmFamily = 'classical' | 'lattice' | 'hash_based' | 'hybrid';

// ============================================================================
// Configuration Types
// ============================================================================

/** Crypto SDK configuration */
export interface CryptoConfig {
  apiKey: string;
  endpoint?: string;
  timeout?: number;
  retries?: number;
  debug?: boolean;
  defaultNetwork?: Network;
}

/** Key derivation configuration */
export interface DerivationConfig {
  /** Salt for HKDF (optional) */
  salt?: Uint8Array;
  /** Info/context for domain separation */
  info?: Uint8Array;
  /** Output key length in bytes */
  outputLength?: number;
}

/** Password derivation configuration */
export interface PasswordDerivationConfig {
  /** Salt (minimum 8 bytes) */
  salt: Uint8Array;
  /** Number of PBKDF2 iterations (minimum 10,000) */
  iterations: number;
  /** Output key length in bytes (max 64) */
  outputLength?: number;
}

/** BIP-44 derivation path */
export interface DerivationPath {
  /** Account number (hardened) */
  account: number;
  /** Change: 0 = external, 1 = internal */
  change: number;
  /** Address index */
  index: number;
}

// ============================================================================
// Key Types
// ============================================================================

/** Ed25519 public key (32 bytes) */
export interface Ed25519PublicKey {
  bytes: Uint8Array;
}

/** Dilithium3 public key (~1952 bytes) */
export interface Dilithium3PublicKey {
  bytes: Uint8Array;
}

/** Hybrid public key (Ed25519 + Dilithium3) */
export interface HybridPublicKey {
  /** Ed25519 component (32 bytes) */
  ed25519: Uint8Array;
  /** Dilithium3 component (~1952 bytes) */
  dilithium: Uint8Array;
}

/** Secret key (master seed) */
export interface SecretKey {
  /** Ed25519 seed (32 bytes) */
  ed25519Seed: Uint8Array;
  /** Master seed for derivation (64 bytes) */
  masterSeed: Uint8Array;
}

/** Falcon public key */
export interface FalconPublicKey {
  variant: FalconVariant;
  bytes: Uint8Array;
}

/** Falcon secret key */
export interface FalconSecretKey {
  variant: FalconVariant;
  bytes: Uint8Array;
}

/** SPHINCS+ public key */
export interface SphincsPublicKey {
  variant: SphincsVariant;
  bytes: Uint8Array;
}

/** SPHINCS+ secret key */
export interface SphincsSecretKey {
  variant: SphincsVariant;
  bytes: Uint8Array;
}

// ============================================================================
// Signature Types
// ============================================================================

/** Ed25519 signature (64 bytes) */
export interface Ed25519Signature {
  bytes: Uint8Array;
}

/** Dilithium3 signature (~3293 bytes) */
export interface Dilithium3Signature {
  bytes: Uint8Array;
}

/** Hybrid signature (Ed25519 + Dilithium3) */
export interface HybridSignature {
  /** Ed25519 component (64 bytes) */
  ed25519: Uint8Array;
  /** Dilithium3 component (~3293 bytes) */
  dilithium: Uint8Array;
}

/** Falcon signature */
export interface FalconSignature {
  variant: FalconVariant;
  bytes: Uint8Array;
}

/** SPHINCS+ signature */
export interface SphincsSignature {
  variant: SphincsVariant;
  bytes: Uint8Array;
}

// ============================================================================
// Keypair Types
// ============================================================================

/** Ed25519 keypair */
export interface Ed25519Keypair {
  publicKey: Ed25519PublicKey;
  secretKey: Uint8Array;
}

/** Hybrid keypair (Ed25519 + Dilithium3) */
export interface HybridKeypair {
  publicKey: HybridPublicKey;
  secretKey: SecretKey;
  /** Get address for this keypair */
  address(network: Network): string;
}

/** Falcon keypair */
export interface FalconKeypair {
  variant: FalconVariant;
  publicKey: FalconPublicKey;
  secretKey: FalconSecretKey;
}

/** SPHINCS+ keypair */
export interface SphincsKeypair {
  variant: SphincsVariant;
  publicKey: SphincsPublicKey;
  secretKey: SphincsSecretKey;
}

// ============================================================================
// Mnemonic Types
// ============================================================================

/** Mnemonic phrase representation */
export interface Mnemonic {
  /** The mnemonic phrase */
  phrase: string;
  /** Individual words */
  words: string[];
  /** Word count */
  wordCount: MnemonicWordCount;
  /** Entropy bytes */
  entropy: Uint8Array;
}

/** Mnemonic validation result */
export interface MnemonicValidation {
  valid: boolean;
  error?: string;
}

// ============================================================================
// Address Types
// ============================================================================

/** Blockchain address */
export interface Address {
  /** Address string (bech32 encoded) */
  address: string;
  /** Network */
  network: Network;
  /** Public key hash */
  pubkeyHash: Uint8Array;
}

// ============================================================================
// Hash Types
// ============================================================================

/** 256-bit hash */
export interface Hash256 {
  bytes: Uint8Array;
  hex: string;
}

// ============================================================================
// Algorithm Negotiation Types
// ============================================================================

/** Algorithm capabilities */
export interface AlgorithmCapabilities {
  /** Supported post-quantum algorithms */
  pqAlgorithms: PqAlgorithm[];
  /** Classical algorithm support */
  classical: boolean;
  /** Hybrid mode support */
  hybrid: boolean;
  /** Preferred algorithm */
  preferred?: PqAlgorithm;
}

/** Negotiation policy */
export interface NegotiationPolicy {
  /** Required minimum security level (bits) */
  minSecurityLevel: number;
  /** Prefer smaller signatures */
  preferCompact: boolean;
  /** Allow classical-only fallback */
  allowClassical: boolean;
  /** Required algorithm families */
  requiredFamilies: AlgorithmFamily[];
}

/** Negotiation result */
export interface NegotiationResult {
  /** Selected algorithm */
  algorithm: PqAlgorithm;
  /** Security level in bits */
  securityLevel: number;
  /** Algorithm family */
  family: AlgorithmFamily;
  /** Is hybrid mode */
  hybrid: boolean;
}

/** Session parameters after negotiation */
export interface SessionParams {
  /** Negotiated algorithm */
  algorithm: PqAlgorithm;
  /** Session key (if established) */
  sessionKey?: Uint8Array;
  /** Expiry timestamp */
  expiresAt?: number;
}

// ============================================================================
// Error Types
// ============================================================================

/** Crypto error codes */
export type CryptoErrorCode =
  | 'INVALID_MNEMONIC'
  | 'INVALID_WORD_COUNT'
  | 'INVALID_SEED'
  | 'INVALID_KEY'
  | 'INVALID_SIGNATURE'
  | 'VERIFICATION_FAILED'
  | 'DERIVATION_FAILED'
  | 'ALGORITHM_MISMATCH'
  | 'NEGOTIATION_FAILED'
  | 'NETWORK_ERROR'
  | 'TIMEOUT';

/** Crypto exception */
export class CryptoError extends Error {
  constructor(
    message: string,
    public readonly code?: CryptoErrorCode,
    public readonly cause?: unknown
  ) {
    super(message);
    this.name = 'CryptoError';
  }
}

// ============================================================================
// Constants
// ============================================================================

export const CryptoConstants = {
  /** Ed25519 public key size in bytes */
  ED25519_PUBLIC_KEY_SIZE: 32,
  /** Ed25519 secret key size in bytes */
  ED25519_SECRET_KEY_SIZE: 32,
  /** Ed25519 signature size in bytes */
  ED25519_SIGNATURE_SIZE: 64,
  /** Dilithium3 public key size in bytes */
  DILITHIUM3_PUBLIC_KEY_SIZE: 1952,
  /** Dilithium3 signature size in bytes */
  DILITHIUM3_SIGNATURE_SIZE: 3293,
  /** Hybrid signature size (Ed25519 + Dilithium3) */
  HYBRID_SIGNATURE_SIZE: 64 + 3293,
  /** Falcon-512 signature size */
  FALCON512_SIGNATURE_SIZE: 690,
  /** Falcon-512 public key size */
  FALCON512_PUBLIC_KEY_SIZE: 897,
  /** Falcon-1024 signature size */
  FALCON1024_SIGNATURE_SIZE: 1330,
  /** Falcon-1024 public key size */
  FALCON1024_PUBLIC_KEY_SIZE: 1793,
  /** SPHINCS+-128s signature size */
  SPHINCS128S_SIGNATURE_SIZE: 7856,
  /** SPHINCS+-192s signature size */
  SPHINCS192S_SIGNATURE_SIZE: 16224,
  /** SPHINCS+-256s signature size */
  SPHINCS256S_SIGNATURE_SIZE: 29792,
  /** BIP-44 coin type for Synor */
  COIN_TYPE: 0x5359,
  /** Minimum PBKDF2 iterations */
  MIN_PBKDF2_ITERATIONS: 10000,
  /** Minimum salt length for password derivation */
  MIN_SALT_LENGTH: 8,
  /** Default API endpoint */
  DEFAULT_ENDPOINT: 'https://crypto.synor.io/v1',
} as const;

/** Algorithm size comparison */
export const AlgorithmSizes = {
  ed25519: { signature: 64, publicKey: 32 },
  dilithium3: { signature: 3293, publicKey: 1952 },
  hybrid: { signature: 3357, publicKey: 1984 },
  falcon512: { signature: 690, publicKey: 897 },
  falcon1024: { signature: 1330, publicKey: 1793 },
  sphincs128s: { signature: 7856, publicKey: 32 },
  sphincs192s: { signature: 16224, publicKey: 48 },
  sphincs256s: { signature: 29792, publicKey: 64 },
} as const;
