/**
 * Adapter-facing shared types. Kept separate from core types because they
 * describe the boundary between Mailforge and external systems (CRM, send
 * provider), not internal data structures.
 */

/**
 * Normalized Recipient/Contact representation passed between adapters and
 * mailforge modules. Whatever your CRM looks like internally, the adapter must
 * map records to this shape before returning them to the mailforge core.
 *
 * `customData` is the escape hatch for template tags — any key here can be
 * referenced in MJML as `{{KEY}}` and will be substituted at send time.
 */
export interface Contact {
  /** Stable external ID (CRM-specific, opaque to mailforge). */
  externalId: string;

  email: string;
  firstName?: string;
  lastName?: string;
  salutation?: string;

  /** Optional company affiliation (e.g. for B2B segmenting). */
  company?: string;

  /** Locale hint (e.g. "de-DE", "en-US"). */
  locale?: string;

  /** Free-form custom fields used for template tag substitution. */
  customData?: Record<string, string | number | boolean | null>;

  /** Server-reported unsubscribe flag (mailforge will skip these). */
  unsubscribed?: boolean;
}

export interface ContactFilter {
  /** Workspace scope; required for security in multi-tenant setups. */
  workspaceId: string;
  /** Adapter-specific segment IDs. */
  segments?: string[];
  /** Pagination. */
  limit?: number;
  offset?: number;
  /** Custom filter pairs, adapter-interpreted. */
  customFilters?: Record<string, unknown>;
}

export interface ConversionEvent {
  /** Maps back to the Contact.externalId. */
  contactId: string;
  occurredAt: Date;
  /** Optional monetary value. */
  amount?: number;
  currency?: string;
  /** Adapter-specific reference (order ID etc.). */
  externalRef?: string;
  /** Free-form metadata passed through to attribution. */
  meta?: Record<string, unknown>;
}

/**
 * Generic send-mail input. SendProvider implementations translate this into
 * provider-specific calls (SMTP, M365 Graph, Resend HTTP, etc.).
 */
export interface SendMailInput {
  /** Workspace this send belongs to — adapter may use it for sender-routing. */
  workspaceId: string;

  from: { email: string; name?: string };
  to: string[];
  subject: string;
  bodyHtml: string;
  bodyText: string;

  /** Optional copy / blind copy. */
  cc?: string[];
  bcc?: string[];

  /** Optional Reply-To override. */
  replyTo?: { email: string; name?: string };

  /** Custom headers (e.g. List-Unsubscribe). */
  headers?: Record<string, string>;

  /**
   * Idempotency hint — if the same messageId is sent twice within a short
   * window, provider may reject the duplicate (RFC 5322 Message-ID).
   */
  messageId?: string;
}

export type SendErrorKind =
  | 'network'
  | 'auth'
  | 'rate-limit'
  | 'config'
  | 'rejected'
  | 'unknown';

export interface SendResult {
  ok: boolean;
  /** Provider-assigned message ID for tracking. */
  messageId?: string;
  /** Human-readable error description for logs. */
  error?: string;
  errorKind?: SendErrorKind;
  /** HTTP status if relevant (for debugging). */
  httpStatus?: number;
}
