import type { BaseIntegrationAdapter } from '../../../base-integration-adapter'
import { ToolingError } from '../../../../types'
import type { ExecutionContext } from '../../../../../base/types'
import { sendEmail } from './fetch/send-email/index'
import { getEmail } from './fetch/get-email/index'

/**
 * Resend credentials format
 * Stored in credentials table, encrypted
 *
 * Uses API key authentication only
 */
interface ResendCredentials {
  apiKey: string // API key (re_xxxxxxxxx)
}

/**
 * Send email parameters
 */
interface SendEmailParams {
  from: string
  to: string | string[]
  subject: string
  html?: string
  text?: string
  replyTo?: string | string[]
  cc?: string | string[]
  bcc?: string | string[]
  headers?: Record<string, string>
  tags?: Array<{ name: string; value: string }>
}

/**
 * Get email parameters
 */
interface GetEmailParams {
  emailId: string
}

/**
 * Resend integration adapter
 *
 * Provides access to Resend transactional email API for sending emails
 * with unsubscribe headers (RFC 8058 compliant).
 *
 * @example
 * ```typescript
 * const adapter = new ResendAdapter()
 * const result = await adapter.call(
 *   'sendEmail',
 *   {
 *     from: 'Alex <alexl@elevasis.io>',
 *     to: 'john@example.com',
 *     subject: 'Reminder',
 *     html: '<p>Hello</p>'
 *   },
 *   { apiKey: 're_xxx' },
 *   context
 * )
 * ```
 */
export class ResendAdapter implements BaseIntegrationAdapter {
  readonly name = 'resend'

  /**
   * Call Resend API method
   */
  async call(
    method: string,
    params: unknown,
    credentials: Record<string, unknown>,
    context?: ExecutionContext
  ): Promise<unknown> {
    // Validate credentials first
    if (!this.validateCredentials(credentials)) {
      throw new ToolingError('credentials_invalid', 'Invalid Resend credentials', {
        integration: this.name,
        organizationId: context?.organizationId
      })
    }

    // Safe to cast after validation confirms apiKey exists and is valid
    const creds = credentials as unknown as ResendCredentials

    // Route to method handler - delegate to fetch functions
    switch (method) {
      case 'sendEmail':
        return sendEmail(creds, params as SendEmailParams, context)
      case 'getEmail':
        return getEmail(creds, params as GetEmailParams, context)
      default:
        throw new ToolingError('method_not_found', `Unknown Resend method: ${method}`, {
          integration: this.name,
          method,
          organizationId: context?.organizationId
        })
    }
  }

  /**
   * Validate Resend credentials
   */
  validateCredentials(credentials: Record<string, unknown>): boolean {
    const creds = credentials as unknown as ResendCredentials
    // Require API key (should start with 're_')
    return !!creds.apiKey && typeof creds.apiKey === 'string' && creds.apiKey.length > 0
  }
}
