import type { IngestInteractionRequest, ScopeVector } from '@insignia/iios-contracts';

export interface AdapterCapability {
  canReceive: boolean;
  canSend: boolean;
  supportsThreads?: boolean;
  /** For "changed-only" providers (calendar-style) that need a follow-up fetch. */
  requiresFollowupFetch?: boolean;
}

export interface NormalizeContext {
  scope: ScopeVector;
}

export interface OutboundCommandInput {
  channelType: string;
  target: string;
  payload: Record<string, unknown>;
}

export interface SendResult {
  providerRef: string;
  outcome: string;
  latencyMs: number;
}

/**
 * The anti-corruption contract every provider implements. An adapter's job ends
 * at producing an IngestInteractionRequest — the kernel's IngestService does the
 * rest. `fetch` is the declared-but-unimplemented seam for providers that only
 * notify "something changed".
 */
export interface ChannelAdapter {
  channelType: string;
  capability: AdapterCapability;
  verifySignature(rawBody: string, headers: Record<string, string | undefined>, secret: string): boolean;
  /** Provider-native id used to dedup replays/retries at the inbound edge (e.g. eventId, Message-ID). */
  externalEventId?(payload: unknown): string | undefined;
  normalize(payload: unknown, ctx: NormalizeContext): IngestInteractionRequest;
  fetch?(ref: string): Promise<unknown>;
  send(cmd: OutboundCommandInput): Promise<SendResult>;
}
