import type { MailAttachment, InboxItem, InboxState, MailMessage, MailPerson } from './types';

/**
 * The inbox seam. A host implements this; the SDK renders it. Mirrors MessagingAdapter's philosophy:
 * `listInbox` returns the UNIFIED feed (work items + mail folded in) so the folding logic lives in
 * one place (the adapter, which knows both sources). Compose methods are optional and degrade.
 */
export interface InboxAdapter {
  /** The unified inbox: work items + mail threads as rows, filtered by state (mail shows in OPEN). */
  listInbox(state?: InboxState): Promise<InboxItem[]>;

  /** Transition a work item's state (Done/Snooze/Archive…). Mail rows are not transitioned. */
  transition(id: string, state: InboxState): Promise<void>;

  /** Messages of one mail thread (HTML + text parts) for the reader. */
  mailHistory(threadId: string): Promise<MailMessage[]>;

  /** Reply into an existing mail thread, optionally with one attachment. */
  mailReply(threadId: string, content: string, attachment?: MailAttachment): Promise<void>;

  // ── Attachments (optional) — absent hides the attach affordance ──
  /** Upload a file to storage, returning a reference to send with a reply/compose. */
  uploadAttachment?(file: File): Promise<MailAttachment>;

  /** Resolve a short-lived URL to view/download an attachment. Absent => attachment chips are
   *  shown but not clickable. */
  downloadAttachment?(attachment: MailAttachment): Promise<string>;

  // ── Compose (optional) — absent hides the "New message" affordance ──
  /** People you can compose an in-app message to. */
  directory?(): Promise<MailPerson[]>;
  /** App-to-app mail (no SMTP) to a registered user's in-app inbox. */
  composeInternal?(recipientUserId: string, subject: string, text: string, attachments?: MailAttachment[]): Promise<void>;
  /** External email (SMTP) to an address. */
  composeExternal?(target: string, subject: string, text: string, attachments?: MailAttachment[]): Promise<void>;
}
