import { ToolingError } from '../../../../../../types'
import type { ExecutionContext } from '../../../../../../../base/types'
import { withRetry, createHttpError, DEFAULT_RETRY_POLICY } from '../../../../../../../../../platform/resilience'
import type { ResendCredentials, GetEmailParams, GetEmailResult, ResendGetEmailResponse } from '../utils/types'

/**
 * Get email status from Resend API
 *
 * @param credentials - Resend API credentials (apiKey)
 * @param params - Email ID to retrieve
 * @param context - Execution context for logging
 * @returns Email details including delivery status
 * @throws ToolingError if retrieval fails
 *
 * @example
 * const result = await getEmail(
 *   { apiKey: 're_xxx' },
 *   { emailId: '49a3999c-0ce1-4ea6-ab68-afcd6dc2e794' },
 *   context
 * )
 * // result.lastEvent: 'sent', 'delivered', 'bounced', 'complained', 'failed'
 */
export async function getEmail(
  credentials: ResendCredentials,
  params: GetEmailParams,
  context?: ExecutionContext
): Promise<GetEmailResult> {
  const { apiKey } = credentials
  const { emailId } = params

  // Validate required parameters
  if (!apiKey) {
    throw new ToolingError('credentials_invalid', 'Resend API credentials must include apiKey', {
      integration: 'resend',
      method: 'getEmail'
    })
  }

  if (!emailId) {
    throw new ToolingError('validation_error', 'Email ID is required', { integration: 'resend', method: 'getEmail' })
  }

  // Build URL
  const url = `https://api.resend.com/emails/${encodeURIComponent(emailId)}`

  try {
    // Execute with retry logic
    const response = await withRetry(async () => {
      const res = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${apiKey}`
        }
      })

      // Handle HTTP errors
      if (!res.ok) {
        throw await createHttpError(res, {
          integration: 'resend',
          method: 'getEmail',
          organizationId: context?.organizationId
        })
      }

      return res
    }, DEFAULT_RETRY_POLICY)

    // Parse response
    const result = (await response.json()) as ResendGetEmailResponse

    // Log success
    if (context?.logger) {
      context.logger.info(
        `[ResendAdapter] Email retrieved: organizationId=${context.organizationId} executionId=${context.executionId} emailId=${result.id} lastEvent=${result.last_event}`
      )
    }

    // Return standardized result (camelCase)
    return {
      id: result.id,
      to: result.to,
      from: result.from,
      subject: result.subject,
      lastEvent: result.last_event,
      createdAt: result.created_at
    }
  } catch (error) {
    // Re-throw ToolingError as-is
    if (error instanceof ToolingError) {
      throw error
    }

    // Wrap unknown errors
    throw new ToolingError('api_error', `Failed to get email from Resend: ${(error as Error).message}`, {
      integration: 'resend',
      method: 'getEmail',
      organizationId: context?.organizationId,
      emailId,
      originalError: error
    })
  }
}
