import {
  AddressTrackingResult,
  DepositEvent,
  TrackedAddressRegistration,
  WebhookShardMetadata,
} from "../types";

/**
 * Manages registration of wallet addresses to an active-monitoring channel
 * (e.g. webhook subscriptions).  A provider that uses polling instead of
 * webhooks would return isEnabled() = false so the system falls back to
 * reconciliation-based detection.
 */
export interface IAddressTrackerPort {
  isEnabled(): boolean;
  addAddresses(registrations: TrackedAddressRegistration[]): Promise<AddressTrackingResult>;
  removeAddresses(addresses: string[]): Promise<{ removed: number; skipped: number }>;
  getTrackingMetadata(): Promise<WebhookShardMetadata[]>;
}

/**
 * Source of truth for which on-chain addresses the system currently monitors,
 * expressed as flat chain/address pairs regardless of how the provider
 * internally organises them (shards, webhooks, etc.).
 */
export interface IRegisteredAddressPort {
  getAllTrackedAddresses(): Promise<Array<{ chainType: string; address: string }>>;
}

export interface DepositScanRequest {
  chainType: string;
  address: string;
  fromBlock: string;
}

/**
 * Provider adapter that performs historical transfer scanning and returns
 * fully-normalised DepositEvents the core reconciliation loop can process
 * without knowing anything about the underlying provider.
 */
export interface IDepositScannerPort {
  isEnabled(): boolean;
  scanDeposits(requests: DepositScanRequest[]): Promise<Map<string, DepositEvent[]>>;
  getBlockNumber(chainType: string): Promise<number>;
  /** Stable key used to correlate results back to the originating request. */
  resultKey(chainType: string, address: string): string;
}

export interface WebhookProcessResult {
  events: DepositEvent[];
  metrics: {
    ignored: number;
    unsupported: number;
    reorgEvents: number;
  };
}

/**
 * Handles the full inbound webhook pipeline: signature verification, payload
 * validation, and normalisation to canonical DepositEvents.  Each provider
 * ships its own adapter; the route handler is provider-agnostic.
 */
export interface IWebhookProcessorPort {
  process(
    body: unknown,
    headers: Record<string, string | string[] | undefined>,
    rawBody: string | undefined
  ): Promise<WebhookProcessResult>;
}
