/**
 * Attachments + sources attached to a chat message.
 */

/**
 * Rich-preview payload for a localpreview-style attachment card. Serializable
 * JSON only (no React nodes) so it survives history persistence + SSE — the
 * render seam already exists (`AttachmentRendererMap`); this is the DATA that
 * feeds it. One generic bag instead of a typed field per media kind: a host
 * populates `kind` + `fields[]` (duration, dimensions, pages, EXIF…) and the
 * default/per-type renderer reads it. Absent → renderer falls back to the
 * name+thumbnail chip.
 */
export interface AttachmentPreview {
  /** Drives which rich card the renderer mounts (audio/image/pdf/doc/…). */
  kind: string;
  title?: string;
  /** Cover / first-page thumbnail (audio art, pdf page-1). */
  thumbnail?: string;
  /** Ordered label/value rows the card renders (duration, dims, pages, EXIF…). */
  fields?: { label: string; value: string }[];
}

export interface ChatAttachment {
  id: string;
  type: 'image' | 'file' | 'audio' | 'video' | 'text';
  /**
   * Object-URL / remote URL for binary attachments. Empty string for
   * `type:'text'` chunks — those carry their payload in `text`, not a URL.
   */
  url: string;
  thumbnailUrl?: string;
  name?: string;
  mimeType?: string;
  sizeBytes?: number;
  status?: 'uploading' | 'ready' | 'error';
  /** 0..1 while uploading. */
  progress?: number;
  /**
   * Raw text payload for `type:'text'` chunks — the "Pasted text"
   * attachment minted when a long paste is converted into a chip
   * instead of dumped into the textarea (ChatGPT/Claude behaviour).
   * Preserves exact content: newlines, indentation, stack traces.
   */
  text?: string;
  /**
   * Optional rich-preview payload for a localpreview-style card (audio
   * cover+duration, image thumbnail+EXIF, pdf pages, OCR metadata…).
   * Serializable JSON; persists through history/SSE. Absent → the default
   * renderer falls back to the name+thumbnail chip.
   */
  preview?: AttachmentPreview;
}

export interface ChatSource {
  title: string;
  url: string;
  snippet?: string;
  chunkIndex?: number;
}
