/**
 * TSS Protocol Domain Service
 *
 * Domain service interface for TSS (Threshold Signature Scheme) operations.
 * This defines the domain contract - actual implementation will be in infrastructure.
 */

import { Threshold, PublicKey, Signature, MessageHash } from '../value-objects';
import { KeyCurve } from '../enums';

/**
 * Participant information for TSS protocol
 */
export interface TSSParticipant {
  partyId: string;
  partyIndex: number;
}

/**
 * Result of key generation
 */
export interface KeygenResult {
  shareData: Buffer;        // Raw share data to be encrypted
  publicKey: string;        // Group public key (hex)
  partyIndex: number;       // This party's index
}

/**
 * Result of signing
 */
export interface SigningResult {
  signature: string;        // Signature (hex)
  r: string;                // R component
  s: string;                // S component
  v?: number;               // Recovery parameter (for Ethereum)
}

/**
 * Configuration for TSS operations
 */
export interface TSSConfig {
  curve: KeyCurve;
  timeout: number;          // Operation timeout in milliseconds
}

/**
 * Message for inter-party communication
 */
export interface TSSMessage {
  fromParty: string;
  toParties?: string[];     // undefined means broadcast
  roundNumber: number;
  payload: Buffer;
}

/**
 * TSS Protocol Domain Service Interface
 *
 * This interface defines what TSS operations the domain needs.
 * The actual TSS-lib implementation is an infrastructure concern.
 */
export interface TSSProtocolDomainService {
  /**
   * Initialize and run key generation protocol
   *
   * @param partyId - This party's identifier
   * @param participants - All participants in the protocol
   * @param threshold - The threshold configuration
   * @param config - TSS configuration
   * @param messageSender - Callback for sending messages to other parties
   * @param messageReceiver - Async iterator for receiving messages
   * @returns KeygenResult with share data and public key
   */
  runKeygen(
    partyId: string,
    participants: TSSParticipant[],
    threshold: Threshold,
    config: TSSConfig,
    messageSender: (msg: TSSMessage) => Promise<void>,
    messageReceiver: AsyncIterable<TSSMessage>,
  ): Promise<KeygenResult>;

  /**
   * Initialize and run signing protocol
   *
   * @param partyId - This party's identifier
   * @param participants - Signing participants
   * @param shareData - This party's share data (decrypted)
   * @param messageHash - Hash of message to sign
   * @param threshold - The threshold configuration
   * @param config - TSS configuration
   * @param messageSender - Callback for sending messages
   * @param messageReceiver - Async iterator for receiving messages
   * @returns SigningResult with signature
   */
  runSigning(
    partyId: string,
    participants: TSSParticipant[],
    shareData: Buffer,
    messageHash: MessageHash,
    threshold: Threshold,
    config: TSSConfig,
    messageSender: (msg: TSSMessage) => Promise<void>,
    messageReceiver: AsyncIterable<TSSMessage>,
  ): Promise<SigningResult>;

  /**
   * Run key refresh protocol (proactive security)
   *
   * @param partyId - This party's identifier
   * @param participants - All participants
   * @param oldShareData - Current share data
   * @param threshold - The threshold configuration
   * @param config - TSS configuration
   * @param messageSender - Callback for sending messages
   * @param messageReceiver - Async iterator for receiving messages
   * @returns New share data (public key remains the same)
   */
  runKeyRefresh(
    partyId: string,
    participants: TSSParticipant[],
    oldShareData: Buffer,
    threshold: Threshold,
    config: TSSConfig,
    messageSender: (msg: TSSMessage) => Promise<void>,
    messageReceiver: AsyncIterable<TSSMessage>,
  ): Promise<{ newShareData: Buffer }>;

  /**
   * Verify a signature against a public key
   *
   * @param publicKey - The group public key
   * @param messageHash - The message hash
   * @param signature - The signature to verify
   * @param curve - The elliptic curve
   * @returns true if signature is valid
   */
  verifySignature(
    publicKey: PublicKey,
    messageHash: MessageHash,
    signature: Signature,
    curve: KeyCurve,
  ): boolean;

  /**
   * Derive child key from master key (for HD-like derivation)
   *
   * @param shareData - The master share data
   * @param derivationPath - The derivation path
   * @returns Derived share data
   */
  deriveChildKey(
    shareData: Buffer,
    derivationPath: string,
  ): Promise<Buffer>;
}

/**
 * Symbol for dependency injection
 */
export const TSS_PROTOCOL_SERVICE = Symbol('TSS_PROTOCOL_SERVICE');
