import { withRetry, createHttpError, DEFAULT_RETRY_POLICY } from '../../../../../../../../../platform/resilience'
import type { ExecutionContext } from '../../../../../../../base/types'

interface InstantlyCredentials {
  apiKey: string
}

export interface GetEmailsParams {
  email_id?: string
  search?: string
  campaign_id?: string
  lead?: string
  email_type?: 'received' | 'sent' | 'manual'
  eaccount?: string
  sort_order?: 'asc' | 'desc'
  preview_only?: boolean
  is_unread?: boolean
  limit?: number
  starting_after?: string
}

export interface GetEmailsResult {
  emails: unknown[]
  total_count: number
  next_starting_after?: string
}

const INSTANTLY_API_BASE = 'https://api.instantly.ai/api/v2'

/**
 * Get emails from Instantly workspace
 *
 * Retrieves email data with optional filtering and pagination.
 * Can fetch a specific email by ID or list emails with filters.
 *
 * @param credentials - Instantly API key
 * @param params - Email ID, search, filters, and pagination options
 * @param context - Execution context for logging
 * @returns Email data and pagination info
 */
export async function getEmails(
  credentials: InstantlyCredentials,
  params: GetEmailsParams,
  context?: ExecutionContext
): Promise<GetEmailsResult> {
  const { apiKey } = credentials
  const {
    email_id,
    search,
    campaign_id,
    lead,
    email_type,
    eaccount,
    sort_order,
    preview_only,
    is_unread,
    limit,
    starting_after
  } = params

  // If specific email ID provided, fetch that email
  if (email_id) {
    const emailUrl = `${INSTANTLY_API_BASE}/emails/${email_id}`

    if (context?.logger) {
      context.logger.info(`[InstantlyAdapter] Fetching email: email_id=${email_id} executionId=${context.executionId}`)
    }

    const response = await withRetry(async () => {
      const res = await fetch(emailUrl, {
        headers: {
          Authorization: `Bearer ${apiKey}`
        }
      })

      if (!res.ok) {
        throw await createHttpError(res, {
          integration: 'instantly',
          method: 'getEmails',
          organizationId: context?.organizationId
        })
      }

      return res.json()
    }, DEFAULT_RETRY_POLICY)

    const email = response.data || response

    if (context?.logger) {
      context.logger.info(`[InstantlyAdapter] Email fetched: email_id=${email_id} executionId=${context.executionId}`)
    }

    return {
      emails: [email],
      total_count: 1
    }
  }

  // Otherwise, list emails with filters and cursor pagination
  const queryParams = new URLSearchParams()
  if (limit) queryParams.set('limit', String(limit))
  if (search) queryParams.set('search', search)
  if (campaign_id) queryParams.set('campaign_id', campaign_id)
  if (lead) queryParams.set('lead', lead)
  if (email_type) queryParams.set('email_type', email_type)
  if (eaccount) queryParams.set('eaccount', eaccount)
  if (sort_order) queryParams.set('sort_order', sort_order)
  if (preview_only !== undefined) queryParams.set('preview_only', String(preview_only))
  if (is_unread !== undefined) queryParams.set('is_unread', String(is_unread))
  if (starting_after) queryParams.set('starting_after', starting_after)

  const listUrl = `${INSTANTLY_API_BASE}/emails${queryParams.toString() ? `?${queryParams.toString()}` : ''}`

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Listing emails: limit=${limit} campaign_id=${campaign_id} executionId=${context.executionId}`
    )
  }

  const response = await withRetry(async () => {
    const res = await fetch(listUrl, {
      headers: {
        Authorization: `Bearer ${apiKey}`
      }
    })

    if (!res.ok) {
      throw await createHttpError(res, {
        integration: 'instantly',
        method: 'getEmails',
        organizationId: context?.organizationId
      })
    }

    return res.json()
  }, DEFAULT_RETRY_POLICY)

  // Parse response - handle multiple possible API response shapes
  const rawData = response.data ?? response
  const emails = Array.isArray(rawData) ? rawData : rawData?.items || rawData?.emails || []
  const total_count = emails.length
  const next_starting_after = response.next_starting_after || response.data?.next_starting_after

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Emails fetched: count=${emails.length} total_count=${total_count} executionId=${context.executionId}`
    )
  }

  return {
    emails,
    total_count,
    ...(next_starting_after ? { next_starting_after } : {})
  }
}
