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

interface InstantlyCredentials {
  apiKey: string
}

export interface BulkAddLeadsLead {
  email: string
  first_name?: string
  last_name?: string
  company_name?: string
  website?: string
  custom_variables?: Record<string, string>
}

export interface BulkAddLeadsParams {
  campaign_id: string
  leads: BulkAddLeadsLead[]
}

export interface BulkAddLeadsError {
  email: string
  error: string
}

export interface BulkAddLeadsResult {
  success: boolean
  added_count: number
  failed_count: number
  errors?: BulkAddLeadsError[]
}

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

/**
 * Bulk add leads to an Instantly campaign
 *
 * Adds up to 1,000 leads in a single request to an existing campaign.
 * Supports full lead profiles including custom variables. Each lead
 * must have a valid email address.
 *
 * @param credentials - Instantly API key
 * @param params - Campaign ID and array of leads (max 1,000)
 * @param context - Execution context for logging
 * @returns Result with success status, added count, failed count, and per-lead errors
 */
export async function bulkAddLeads(
  credentials: InstantlyCredentials,
  params: BulkAddLeadsParams,
  context?: ExecutionContext
): Promise<BulkAddLeadsResult> {
  const { apiKey } = credentials
  const { campaign_id, leads } = params

  // Validation
  if (!campaign_id) {
    throw new ToolingError('validation_error', 'Missing required parameter: campaign_id', {
      integration: 'instantly',
      method: 'bulkAddLeads'
    })
  }

  if (!leads || leads.length === 0) {
    throw new ToolingError('validation_error', 'Must provide at least one lead', {
      integration: 'instantly',
      method: 'bulkAddLeads'
    })
  }

  if (leads.length > 1000) {
    throw new ToolingError('validation_error', 'Cannot add more than 1,000 leads per request', {
      integration: 'instantly',
      method: 'bulkAddLeads'
    })
  }

  // Validate each lead has an email
  for (const lead of leads) {
    if (!lead.email) {
      throw new ToolingError('validation_error', 'Each lead must have an email address', {
        integration: 'instantly',
        method: 'bulkAddLeads'
      })
    }
  }

  const bulkLeadsUrl = `${INSTANTLY_API_BASE}/leads/add`

  const requestBody = {
    campaign_id,
    leads: leads.map((lead) => ({
      email: lead.email,
      first_name: lead.first_name,
      last_name: lead.last_name,
      company_name: lead.company_name,
      website: lead.website,
      custom_variables: lead.custom_variables
    }))
  }

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Bulk adding leads to campaign: campaign_id=${campaign_id} lead_count=${leads.length} executionId=${context.executionId}`
    )
  }

  const response = await withRetry(async () => {
    const res = await fetch(bulkLeadsUrl, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    })

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

    return res.json()
  }, DEFAULT_RETRY_POLICY)

  const data = response.data ?? response

  // Parse response - Instantly API v2 /leads/add returns:
  // { status, total_sent, leads_uploaded, in_blocklist, duplicated_leads, skipped_count,
  //   invalid_email_count, incomplete_count, duplicate_email_count, created_leads[] }
  const added_count = data.leads_uploaded ?? data.added_count ?? data.uploaded ?? leads.length
  const failed_count =
    (data.invalid_email_count ?? 0) + (data.incomplete_count ?? 0) + (data.failed_count ?? data.failed ?? 0)
  const errors: BulkAddLeadsError[] | undefined =
    data.errors && Array.isArray(data.errors) && data.errors.length > 0 ? data.errors : undefined

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Bulk leads added: campaign_id=${campaign_id} added_count=${added_count} failed_count=${failed_count} executionId=${context.executionId}`
    )
  }

  return {
    success: failed_count === 0,
    added_count,
    failed_count,
    ...(errors ? { errors } : {})
  }
}
