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 SendReplyParams {
  eaccount: string
  reply_to_uuid: string
  subject: string
  body: {
    text?: string
    html?: string
  }
  timestamp?: string
}

export interface SendReplyResult {
  success: boolean
  email_id: string
  thread_id: string
  sent_at: string
}

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

/**
 * Send a reply to an email thread via Instantly.ai
 *
 * Sends a reply maintaining proper email threading using reply_to_uuid.
 * Supports both text and HTML body formats, and optional scheduled sending.
 *
 * @param credentials - Instantly API key
 * @param params - Email account, reply UUID, subject, body
 * @param context - Execution context for logging
 * @returns Reply confirmation with email ID and thread ID
 */
export async function sendReply(
  credentials: InstantlyCredentials,
  params: SendReplyParams,
  context?: ExecutionContext
): Promise<SendReplyResult> {
  const { apiKey } = credentials
  const { eaccount, reply_to_uuid, subject, body, timestamp } = params

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

  if (!reply_to_uuid) {
    throw new ToolingError('validation_error', 'Missing required parameter: reply_to_uuid', {
      integration: 'instantly',
      method: 'sendReply'
    })
  }

  if (!body.text && !body.html) {
    throw new ToolingError('validation_error', 'Must provide either body.text or body.html', {
      integration: 'instantly',
      method: 'sendReply'
    })
  }

  const replyUrl = `${INSTANTLY_API_BASE}/emails/reply`

  const requestBody: Record<string, unknown> = {
    eaccount,
    reply_to_uuid,
    subject,
    body
  }

  if (timestamp) {
    requestBody.timestamp = timestamp
  }

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Sending reply: eaccount=${eaccount} reply_to_uuid=${reply_to_uuid} hasText=${!!body.text} hasHtml=${!!body.html} scheduled=${!!timestamp} organizationId=${context.organizationId} executionId=${context.executionId}`
    )
  }

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

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

    return res.json()
  }, DEFAULT_RETRY_POLICY)

  const email_id = response.data?.id || response.data?.email_id || ''
  const thread_id = response.data?.thread_id || ''
  const sent_at = response.data?.sent_at || new Date().toISOString()

  if (context?.logger) {
    context.logger.info(
      `[InstantlyAdapter] Reply sent successfully: email_id=${email_id} thread_id=${thread_id} sent_at=${sent_at} organizationId=${context.organizationId} executionId=${context.executionId}`
    )
  }

  return {
    success: true,
    email_id,
    thread_id,
    sent_at
  }
}
