/**
 * Ingestion pipeline types.
 *
 * An IngestSource is an async generator that yields messages from a platform.
 * The pipeline orchestrator consumes these, deduplicates, chunks, embeds, and stores them.
 */

export interface IngestMessage {
  /** Platform-specific unique ID (e.g., Slack ts, iMessage ROWID, Gmail messageId) */
  id: string;
  platform: string;
  /** Contact identifier (email, phone, Slack user ID) */
  contact: string;
  /** Human-readable contact name (if available) */
  contactName?: string;
  /** "sent" = user's own message, "received" = from others */
  direction: "sent" | "received";
  /** Channel or thread identifier */
  channelId: string;
  channelName?: string;
  threadId?: string;
  content: string;
  timestamp: Date;
  metadata?: Record<string, unknown>;
}

export interface IngestOptions {
  /** Only ingest messages after this date */
  since?: Date;
  /** Filter to a specific contact */
  contact?: string;
  /** Dry run — count messages without storing */
  dryRun?: boolean;
  /** Batch size for embedding calls */
  embeddingBatchSize?: number;
  /** Run type: full (initial) or delta (incremental) */
  runType?: "full" | "delta";
  /** Cron-style interval for the delta-sync job seeded after a full ingest (e.g. "6h", "1h"). Defaults to the DB default "6h" when omitted. */
  deltaSchedule?: string;
  /**
   * For sources that support multiple accounts (currently Gmail), restrict
   * to a single account by email. If omitted, the source iterates every
   * authorized account.
   */
  account?: string;
  /** Owner of the imported memory. Resolved via resolveMemoryUserId; defaults to the local owner. */
  userId?: string;
}

export interface IngestProgress {
  platform: string;
  messagesProcessed: number;
  messagesSkipped: number;
  /** Current cursor for resuming (platform-specific) */
  cursor?: string;
  /** Whether the source has finished yielding */
  done: boolean;
  error?: string;
}

export interface IngestJobRow {
  id: string;
  platform: string;
  source_type: string;
  status: "running" | "completed" | "failed" | "cancelled";
  contact: string | null;
  since_date: Date | null;
  messages_processed: number;
  messages_skipped: number;
  last_cursor: string | null;
  error: string | null;
  started_at: Date;
  finished_at: Date | null;
  last_successful_at: Date | null;
  delta_schedule: string;
  delta_enabled: boolean;
  run_type: "full" | "delta";
}

/**
 * An ingestion source yields messages as an async generator.
 * This allows the pipeline to process messages incrementally
 * without loading everything into memory.
 */
export interface IngestSource {
  readonly platform: string;
  readonly sourceType: string;

  /**
   * Yield messages from the source.
   * @param options - Filtering options (since date, contact, etc.)
   * @param cursor - Resume cursor from a previous run
   */
  ingest(options: IngestOptions, cursor?: string): AsyncGenerator<IngestMessage, void, undefined>;
}
