import type { BaseIntegrationAdapter } from '../../../base-integration-adapter'
import { ToolingError } from '../../../../types'
import type { ExecutionContext } from '../../../../../base/types'
import { createEnvelope } from './fetch/create-envelope'
import { voidEnvelope } from './fetch/void-envelope'
import { downloadDocument } from './fetch/download-document'
import { getEnvelope } from './fetch/get-envelope'
import type {
  SignatureApiCredentials,
  CreateEnvelopeParams,
  VoidEnvelopeParams,
  DownloadDocumentParams,
  GetEnvelopeParams
} from './fetch/utils/types'

/**
 * SignatureAPI integration adapter
 *
 * Provides access to SignatureAPI for electronic signatures.
 * Uses raw fetch (no official SDK) with platform retry/error patterns.
 *
 * @example
 * ```typescript
 * const adapter = new SignatureApiAdapter()
 * const result = await adapter.call(
 *   'createEnvelope',
 *   { title: 'Contract', documents: [...], recipients: [...] },
 *   { apiKey: 'key_test_xxx' },
 *   context
 * )
 * ```
 */
export class SignatureApiAdapter implements BaseIntegrationAdapter {
  readonly name = 'signature-api'

  /**
   * Call SignatureAPI 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 SignatureAPI credentials', {
        integration: this.name,
        organizationId: context?.organizationId
      })
    }

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

    // Route to method handler - delegate to fetch functions
    switch (method) {
      case 'createEnvelope':
        return createEnvelope(creds, params as CreateEnvelopeParams, context)
      case 'voidEnvelope':
        return voidEnvelope(creds, params as VoidEnvelopeParams, context)
      case 'downloadDocument':
        return downloadDocument(creds, params as DownloadDocumentParams, context)
      case 'getEnvelope':
        return getEnvelope(creds, params as GetEnvelopeParams, context)
      default:
        throw new ToolingError('method_not_found', `Unknown SignatureAPI method: ${method}`, {
          integration: this.name,
          method,
          organizationId: context?.organizationId
        })
    }
  }

  /**
   * Validate SignatureAPI credentials
   */
  validateCredentials(credentials: Record<string, unknown>): boolean {
    const creds = credentials as unknown as SignatureApiCredentials
    // API key should start with 'key_'
    return (
      !!creds.apiKey &&
      typeof creds.apiKey === 'string' &&
      creds.apiKey.startsWith('key_')
    )
  }
}
