/**
 * ProviderGateway Types
 *
 * A focused, simplified API for the automation engine to interact with
 * email providers. This is a SUBSET of EmailProviderService, designed
 * specifically for automation workflow actions:
 *   - addContact: Add a contact to a provider's list
 *   - sendCampaign: Create and send a campaign
 *   - triggerAutomation: Trigger a provider-side automation workflow
 *   - getStatus: Check provider connection status
 *
 * Each method includes retry with exponential backoff and error normalization.
 */

// ============================================
// Provider types
// ============================================

export type ProviderName = 'brevo' | 'mailchimp' | 'zoho';

// ============================================
// Input types
// ============================================

export interface AddContactInput {
  /** Contact email address (required) */
  email: string;
  /** Additional provider-specific attributes (e.g. { FNAME: 'John', LNAME: 'Doe' }) */
  attributes?: Record<string, any>;
  /** List IDs to add the contact to */
  listIds?: (number | string)[];
  /** First name */
  firstName?: string;
  /** Last name */
  lastName?: string;
  /** Phone number (with country code, e.g. +919876543210) */
  phone?: string;
  /** Company name */
  company?: string;
}

export interface SendCampaignInput {
  /** Campaign name (internal label) */
  name: string;
  /** Email subject line */
  subject: string;
  /** HTML content for the email body */
  htmlContent?: string;
  /** URL pointing to HTML content (Zoho uses this instead of inline HTML) */
  htmlUrl?: string;
  /** Provider-specific template ID */
  templateId?: number;
  /** Sender information */
  sender: {
    email: string;
    name: string;
    id?: number;
  };
  /** Reply-to email address */
  replyTo?: string;
  /** List IDs to send the campaign to */
  listIds?: (number | string)[];
  /** Schedule date (if null, send immediately) */
  scheduledAt?: Date;
  /** Tags for categorization */
  tags?: string[];
}

export interface TriggerAutomationInput {
  /**
   * Identifier for the automation to trigger.
   * - Brevo: workflow ID (numeric) or event name (string)
   * - Mailchimp: automation/workflow ID
   * - Zoho: workflow key (limited API support)
   */
  identifier: string;
  /** Contact email to add to the automation */
  email: string;
  /** Additional attributes to pass to the automation */
  attributes?: Record<string, any>;
  /** List IDs to subscribe the contact to (feeds into automation) */
  listIds?: (number | string)[];
}

// ============================================
// Output types
// ============================================

export interface ProviderResult<T> {
  /** Whether the operation succeeded */
  success: boolean;
  /** Result data (present when success is true) */
  data?: T;
  /** Error details (present when success is false) */
  error?: ProviderError;
}

export interface AddContactOutput {
  /** Contact ID from the provider */
  contactId: string | number;
  /** Contact email */
  email: string;
  /** Whether the contact was newly created (vs updated) */
  created: boolean;
}

export interface SendCampaignOutput {
  /** Campaign ID from the provider */
  campaignId: string | number;
  /** Campaign status (e.g. 'sent', 'draft', 'scheduled') */
  status: string;
}

export interface TriggerAutomationOutput {
  /** Whether the automation was successfully triggered */
  triggered: boolean;
  /** Optional message with details */
  message?: string;
}

export interface GetStatusOutput {
  /** Whether the provider connection is active */
  connected: boolean;
  /** Which provider this status belongs to */
  provider: ProviderName;
  /** Account email */
  accountEmail?: string;
  /** Account name */
  accountName?: string;
  /** Plan type */
  plan?: string;
  /** Remaining credits (Brevo) */
  credits?: number;
}

// ============================================
// ProviderGateway Interface
// ============================================

export interface ProviderGatewayInterface {
  /**
   * Add a contact to the provider's system.
   * Creates or updates the contact and optionally adds them to specified lists.
   */
  addContact(
    companyId: string,
    input: AddContactInput,
    providerName?: ProviderName
  ): Promise<ProviderResult<AddContactOutput>>;

  /**
   * Create and send (or schedule) a campaign.
   * Two-step process: create the campaign, then send it.
   */
  sendCampaign(
    companyId: string,
    input: SendCampaignInput,
    providerName?: ProviderName
  ): Promise<ProviderResult<SendCampaignOutput>>;

  /**
   * Trigger a provider-side automation workflow.
   * Adds a contact to the automation so it starts receiving the workflow's emails.
   */
  triggerAutomation(
    companyId: string,
    input: TriggerAutomationInput,
    providerName?: ProviderName
  ): Promise<ProviderResult<TriggerAutomationOutput>>;

  /**
   * Check the provider connection status.
   * Returns account info if connected, or connection error if not.
   */
  getStatus(
    companyId: string,
    providerName?: ProviderName
  ): Promise<ProviderResult<GetStatusOutput>>;
}

// ============================================
// Provider Adapter Interface
// ============================================

export interface ProviderAdapter {
  /** Add a contact to the provider */
  addContact(input: AddContactInput): Promise<ProviderResult<AddContactOutput>>;
  /** Create and send a campaign */
  sendCampaign(input: SendCampaignInput): Promise<ProviderResult<SendCampaignOutput>>;
  /** Trigger an automation workflow */
  triggerAutomation(input: TriggerAutomationInput): Promise<ProviderResult<TriggerAutomationOutput>>;
  /** Check connection status */
  getStatus(): Promise<ProviderResult<GetStatusOutput>>;
}

// ============================================
// Import ProviderError for use in type signatures
// (Defined in errorNormalizer.ts)
// ============================================

import { ProviderError } from './errorNormalizer';

// Re-export so consumers can import from this file too
export { ProviderError } from './errorNormalizer';