/**
 * Credential Manager Type Definitions
 *
 * Core types for the multi-platform credential management system.
 * Supports Pacifica (Ed25519), Aster (EIP-191), and Binance (HMAC-SHA256) platforms.
 */

// ============================================================================
// Platform and Signature Type Enums (T013)
// ============================================================================

/**
 * Supported trading platforms
 */
export enum Platform {
  PACIFICA = 'pacifica',
  ASTER = 'aster',
  BINANCE = 'binance',
}

/**
 * Supported signature algorithms
 */
export enum SignatureType {
  ED25519 = 'ed25519',
  EIP191 = 'eip191',
  HMAC_SHA256 = 'hmac-sha256',
}

// ============================================================================
// Credentials Type Definitions (T014)
// ============================================================================

/**
 * Base credentials interface
 */
export interface BaseCredentials {
  type: string
}

/**
 * Ed25519 credentials for Pacifica platform
 */
export interface Ed25519Credentials extends BaseCredentials {
  type: 'ed25519'
  privateKey: string // 64-character hex string
}

/**
 * Pacifica credentials (alias for Ed25519)
 */
export interface PacificaCredentials extends BaseCredentials {
  type: 'pacifica'
  privateKey: string // 64-character hex string
}

/**
 * EIP-191 credentials for Aster platform
 */
export interface Eip191Credentials extends BaseCredentials {
  type: 'eip191'
  privateKey: string // 0x-prefixed hex string
}

/**
 * Aster credentials (alias for EIP-191)
 */
export interface AsterCredentials extends BaseCredentials {
  type: 'aster'
  privateKey: string // 0x-prefixed hex string
}

/**
 * HMAC credentials for Binance platform
 */
export interface HmacCredentials extends BaseCredentials {
  type: 'hmac'
  apiKey: string
  secretKey: string
}

/**
 * Binance credentials (alias for HMAC)
 */
export interface BinanceCredentials extends BaseCredentials {
  type: 'binance'
  apiKey: string
  secretKey: string
}

/**
 * Union type for all credential types
 */
export type Credentials =
  | Ed25519Credentials
  | PacificaCredentials
  | Eip191Credentials
  | AsterCredentials
  | HmacCredentials
  | BinanceCredentials

// ============================================================================
// Account Interface Definition (T015)
// ============================================================================

/**
 * Account configuration from config file
 */
export interface AccountConfig {
  id: string
  platform: Platform
  name: string
  credentials: Credentials
  enabled?: boolean
  metadata?: Record<string, any>
}

/**
 * Runtime account representation
 */
export interface Account {
  id: string
  platform: Platform
  name: string
  credentials: Credentials
  enabled: boolean
  metadata: Record<string, any>
  createdAt: Date
  lastUsed?: Date
}

// ============================================================================
// Signer Interfaces (T016)
// ============================================================================

/**
 * Base signer interface
 */
export interface ISigner {
  /**
   * Platform this signer supports
   */
  readonly platform: Platform

  /**
   * Register platform signing strategy
   * @param platform Platform type
   * @param strategy Signing strategy
   */
  registerStrategy(platform: Platform, strategy: ISignerStrategy): void

  /**
   * Execute signing
   * @param accountId Account ID
   * @param message Message to sign
   * @returns Signing result
   */
  sign(accountId: string, message: Uint8Array): Promise<SignResult>

  /**
   * Verify signature
   * @param accountId Account ID
   * @param message Original message
   * @param signature Signature string
   * @returns Verification result
   */
  verify(accountId: string, message: Uint8Array, signature: string): Promise<boolean>
}

/**
 * Platform-specific signing strategy interface
 */
export interface ISignerStrategy {
  platform: Platform

  /**
   * Execute signing
   * @param message Message to sign
   * @param credentials Account credentials
   * @returns Signature string
   */
  sign(message: Uint8Array, credentials: Credentials): Promise<string>

  /**
   * Verify signature
   * @param message Original message
   * @param signature Signature string
   * @param publicKey Public key for verification
   * @returns Verification result
   */
  verify(message: Uint8Array, signature: string, publicKey: string): Promise<boolean>
}

/**
 * Platform detector interface for smart platform identification
 */
export interface IPlatformDetector {
  /**
   * Detection confidence (0-1)
   */
  confidence: number

  /**
   * Detect platform type from credentials
   * @param credentials Credential object
   * @returns Platform type or null if cannot detect
   */
  detect(credentials: any): Platform | null
}

// ============================================================================
// ConfigLoader Interfaces (T017)
// ============================================================================

/**
 * Configuration loader interface
 */
export interface IConfigLoader {
  /**
   * Load configuration file
   * @param filePath Configuration file path
   * @returns Load result
   */
  loadConfig(filePath: string): Promise<LoadResult>

  /**
   * Watch configuration file for changes
   * @param filePath Configuration file path
   * @param callback Change callback function
   */
  watchConfig(filePath: string, callback: (accounts: Account[]) => void): void

  /**
   * Stop watching configuration file
   */
  stopWatching(): void
}

/**
 * Configuration file structure
 */
export interface ConfigFile {
  version: string
  accounts: AccountConfig[]
  metadata?: Record<string, any>
}

/**
 * Configuration load result
 */
export interface LoadResult {
  success: boolean
  accounts: Account[]
  errors?: string[]
  loadTime: number // milliseconds
  filePath?: string
  version?: string
}

// ============================================================================
// Error Types and Result Interfaces (T018)
// ============================================================================

/**
 * Base error interface
 */
export interface CredentialError {
  code: string
  message: string
  details?: any
  timestamp: Date
}

/**
 * Credential manager error codes
 */
export enum CredentialErrorCode {
  // Configuration errors
  CONFIG_NOT_FOUND = 'CONFIG_NOT_FOUND',
  CONFIG_INVALID_FORMAT = 'CONFIG_INVALID_FORMAT',
  CONFIG_VALIDATION_FAILED = 'CONFIG_VALIDATION_FAILED',

  // Account errors
  ACCOUNT_NOT_FOUND = 'ACCOUNT_NOT_FOUND',
  ACCOUNT_DISABLED = 'ACCOUNT_DISABLED',
  ACCOUNT_INVALID_CREDENTIALS = 'ACCOUNT_INVALID_CREDENTIALS',

  // Signing errors
  SIGNING_FAILED = 'SIGNING_FAILED',
  VERIFICATION_FAILED = 'VERIFICATION_FAILED',
  INVALID_MESSAGE = 'INVALID_MESSAGE',
  INVALID_SIGNATURE = 'INVALID_SIGNATURE',

  // Platform errors
  PLATFORM_NOT_SUPPORTED = 'PLATFORM_NOT_SUPPORTED',
  PLATFORM_DETECTION_FAILED = 'PLATFORM_DETECTION_FAILED',

  // Performance errors
  OPERATION_TIMEOUT = 'OPERATION_TIMEOUT',
  MEMORY_LIMIT_EXCEEDED = 'MEMORY_LIMIT_EXCEEDED',

  // File system errors
  FILE_WATCH_FAILED = 'FILE_WATCH_FAILED',
  FILE_READ_FAILED = 'FILE_READ_FAILED',
  FILE_PERMISSION_DENIED = 'FILE_PERMISSION_DENIED',

  // Additional errors
  MESSAGE_TOO_LARGE = 'MESSAGE_TOO_LARGE',
}

/**
 * Error type aliases for backward compatibility
 */
export enum ErrorType {
  CONFIG_LOAD_ERROR = 'config_load_error',
  VALIDATION_ERROR = 'validation_error',
  SIGNATURE_ERROR = 'signature_error',
  PLATFORM_DETECTION_ERROR = 'platform_detection_error',
}

/**
 * Credential manager specific error
 */
export class CredentialManagerError extends Error {
  public readonly type: ErrorType

  constructor(
    message: string,
    type: ErrorType,
    public readonly details?: any,
  ) {
    super(message)
    this.name = 'CredentialManagerError'
    this.type = type
  }

  // Legacy constructor for backward compatibility
  static fromCode(code: CredentialErrorCode, message: string, details?: any): CredentialManagerError {
    // Map codes to types
    let type: ErrorType
    if (code.includes('CONFIG')) {
      type = ErrorType.CONFIG_LOAD_ERROR
    } else if (code.includes('SIGNING') || code.includes('VERIFICATION')) {
      type = ErrorType.SIGNATURE_ERROR
    } else if (code.includes('PLATFORM')) {
      type = ErrorType.PLATFORM_DETECTION_ERROR
    } else {
      type = ErrorType.VALIDATION_ERROR
    }

    return new CredentialManagerError(message, type, details)
  }
}

/**
 * Sign request interface
 */
export interface SignRequest {
  accountId: string
  message: Uint8Array
  options?: SignOptions
}

/**
 * Sign options
 */
export interface SignOptions {
  timeout?: number // milliseconds
  algorithm?: SignatureType
  encoding?: 'base64' | 'hex' | 'base58'
  metadata?: Record<string, any>
}

/**
 * Sign result interface
 */
export interface SignResult {
  success: boolean
  signature?: string
  algorithm: string
  timestamp: Date
  duration?: number // milliseconds
  error?: string
  metadata?: Record<string, any>
}

/**
 * Verify request interface
 */
export interface VerifyRequest {
  accountId: string
  message: Uint8Array
  signature: string
  options?: VerifyOptions
}

/**
 * Verify options
 */
export interface VerifyOptions {
  timeout?: number // milliseconds
  publicKey?: string
  algorithm?: SignatureType
  metadata?: Record<string, any>
}

/**
 * Verify result interface
 */
export interface VerifyResponse {
  isValid: boolean
  algorithm: string
  timestamp: Date
  duration?: number // milliseconds
  error?: string
  metadata?: Record<string, any>
}

// ============================================================================
// Main Credential Manager Interface
// ============================================================================

/**
 * Main credential manager interface
 */
export interface ICredentialManager {
  /**
   * Load configuration file
   * @param filePath Configuration file path
   * @returns Load result
   */
  loadConfig(filePath: string): Promise<LoadResult>

  /**
   * Watch configuration file for changes
   * @param filePath Configuration file path
   * @param callback Change callback function
   */
  watchConfig(filePath: string, callback: (accounts: Account[]) => void): void

  /**
   * Stop watching configuration file
   */
  stopWatching(): void

  /**
   * Get account by ID
   * @param accountId Account ID
   * @returns Account or null if not found
   */
  getAccount(accountId: string): Account | null

  /**
   * List all accounts
   * @returns Array of accounts
   */
  listAccounts(): Account[]

  /**
   * Sign message with account
   * @param accountId Account ID
   * @param message Message to sign
   * @returns Sign result
   */
  sign(accountId: string, message: Uint8Array): Promise<SignResult>

  /**
   * Verify signature
   * @param accountId Account ID
   * @param message Original message
   * @param signature Signature string
   * @returns Verification result
   */
  verify(accountId: string, message: Uint8Array, signature: string): Promise<boolean>
}

// ============================================================================
// Performance and Monitoring Interfaces
// ============================================================================

/**
 * Performance metrics interface
 */
export interface PerformanceMetrics {
  // Configuration metrics
  configLoadTime: number // milliseconds
  configWatchLatency: number // milliseconds

  // Signing metrics
  signOperationsTotal: number
  signOperationsSuccess: number
  signOperationsFailed: number
  averageSignTime: number // milliseconds
  maxSignTime: number // milliseconds
  minSignTime: number // milliseconds

  // Verification metrics
  verifyOperationsTotal: number
  verifyOperationsSuccess: number
  verifyOperationsFailed: number
  averageVerifyTime: number // milliseconds

  // Memory metrics
  memoryUsage: number // bytes
  accountCount: number

  // Error metrics
  errorsByCode: Record<CredentialErrorCode, number>

  // Timing
  lastResetAt: Date
  uptime: number // milliseconds
}

/**
 * Health check interface
 */
export interface HealthCheck {
  healthy: boolean
  components: {
    configLoader: boolean
    fileWatcher: boolean
    signers: Record<Platform, boolean>
  }
  performance: {
    configLoadTime: number
    averageSignTime: number
    memoryUsage: number
  }
  errors?: CredentialError[]
  timestamp: Date
}
