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

interface TombaCredentials {
  apiKey: string
  apiSecret: string
}

export interface DomainSearchParams {
  domain: string
  limit?: number
  department?: string
  type?: 'personal' | 'generic'
}

export interface DomainSearchEmail {
  email: string
  firstName: string
  lastName: string
  fullName: string
  position: string
  department: string
  verificationDate: string
  verificationStatus: string
  sources: Array<{
    uri: string
    extractedOn: string
    lastSeenOn: string
    stillOnPage: boolean
  }>
}

export interface DomainSearchResult {
  organizationName: string
  domain: string
  emails: DomainSearchEmail[]
}

const TOMBA_API_BASE = 'https://api.tomba.io/v1'

/**
 * Find all email addresses at a company domain via Tomba
 *
 * Searches for all known email addresses at the given domain. Optionally filter
 * by department. Returns enriched data per email including position and
 * verification status.
 *
 * @param credentials - Tomba API key and secret
 * @param params - Domain, optional limit, and optional department filter
 * @param context - Execution context for logging
 * @returns Organization name, domain, and list of found email records
 */
export async function domainSearch(
  credentials: TombaCredentials,
  params: DomainSearchParams,
  context?: ExecutionContext
): Promise<DomainSearchResult> {
  const { apiKey, apiSecret } = credentials
  const { domain, limit, department, type } = params

  if (!domain) {
    throw new Error('domain is required for domainSearch')
  }

  if (context?.logger) {
    context.logger.info(
      `[TombaAdapter] domainSearch: domain=${domain} limit=${limit} department=${department} type=${type} organizationId=${context.organizationId} executionId=${context.executionId}`
    )
  }

  const url = new URL(`${TOMBA_API_BASE}/domain-search`)
  url.searchParams.set('domain', domain)
  if (limit !== undefined) {
    url.searchParams.set('limit', String(limit))
  }
  if (department) {
    url.searchParams.set('department', department)
  }
  if (type) {
    url.searchParams.set('type', type)
  }

  const response = await withRetry(async () => {
    const res = await fetch(url.toString(), {
      method: 'GET',
      headers: {
        'X-Tomba-Key': apiKey,
        'X-Tomba-Secret': apiSecret
      },
      signal: AbortSignal.timeout(60_000)
    })

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

    return res.json()
  }, DEFAULT_RETRY_POLICY)

  const data = response.data ?? {}
  const rawEmails: Array<Record<string, unknown>> = data.emails ?? []

  if (context?.logger) {
    context.logger.info(
      `[TombaAdapter] domainSearch complete: domain=${domain} emailCount=${rawEmails.length} organizationId=${context.organizationId}`
    )
  }

  return {
    organizationName: data.organization_name ?? '',
    domain: data.domain ?? domain,
    emails: rawEmails.map((e) => ({
      email: (e.email as string) ?? '',
      firstName: (e.first_name as string) ?? '',
      lastName: (e.last_name as string) ?? '',
      fullName: (e.full_name as string) ?? '',
      position: (e.position as string) ?? '',
      department: (e.department as string) ?? '',
      verificationDate: ((e.verification as Record<string, unknown>)?.date as string) ?? '',
      verificationStatus: ((e.verification as Record<string, unknown>)?.status as string) ?? '',
      sources: ((e.sources as Array<Record<string, unknown>>) ?? []).map((s) => ({
        uri: (s.uri as string) ?? '',
        extractedOn: (s.extracted_on as string) ?? '',
        lastSeenOn: (s.last_seen_on as string) ?? '',
        stillOnPage: (s.still_on_page as boolean) ?? false
      }))
    }))
  }
}
