import type { BaseIntegrationAdapter } from '../../../base-integration-adapter'
import { ToolingError } from '../../../../types'
import type { ExecutionContext } from '../../../../../base/types'
import { createRecord } from './fetch/create-record/index'
import { updateRecord } from './fetch/update-record/index'
import { listRecords } from './fetch/list-records/index'
import { getRecord } from './fetch/get-record/index'
import { deleteRecord } from './fetch/delete-record/index'
import { listObjects } from './fetch/list-objects/index'
import { listAttributes } from './fetch/list-attributes/index'
import { createAttribute } from './fetch/create-attribute/index'
import { updateAttribute } from './fetch/update-attribute/index'
import { createNote } from './fetch/create-note/index'
import { listNotes } from './fetch/list-notes/index'
import { deleteNote } from './fetch/delete-note/index'
import type {
  ListObjectsParams,
  ListAttributesParams,
  CreateAttributeParams,
  UpdateAttributeParams,
  CreateNoteParams,
  ListNotesParams,
  DeleteNoteParams
} from './fetch/utils/types'

/**
 * Attio credentials format
 * Stored in credentials table, encrypted
 *
 * Uses API key authentication only
 */
interface AttioCredentials {
  apiKey: string // API key for authentication
}

/**
 * Create record parameters
 */
interface CreateRecordParams {
  object: string // Object type (e.g., 'people', 'companies')
  values: Record<string, unknown> // Record field values
}

/**
 * Update record parameters
 */
interface UpdateRecordParams {
  object: string // Object type
  recordId: string // Record ID to update
  values: Record<string, unknown> // Fields to update
}

/**
 * List records parameters
 */
interface ListRecordsParams {
  object: string // Object type
  limit?: number // Max records to return
  offset?: number // Pagination offset
  filter?: Record<string, unknown> // Filter criteria
  sorts?: Array<{ attribute: string; direction: 'asc' | 'desc'; field?: string }> // Sort criteria
}

/**
 * Get record parameters
 */
interface GetRecordParams {
  object: string // Object type
  recordId: string // Record ID
}

/**
 * Delete record parameters
 */
interface DeleteRecordParams {
  object: string // Object type
  recordId: string // Record ID to delete
}

/**
 * Attio integration adapter
 *
 * Provides access to Attio CRM API for managing records, tasks, and notes.
 *
 * @example
 * ```typescript
 * const adapter = new AttioAdapter()
 * const result = await adapter.call(
 *   'createRecord',
 *   { object: 'people', values: { name: 'John Doe' } },
 *   { apiKey: 'your-api-key' },
 *   context
 * )
 * ```
 */
export class AttioAdapter implements BaseIntegrationAdapter {
  readonly name = 'attio'

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

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

    // Route to method handler - delegate to fetch functions
    switch (method) {
      case 'createRecord':
        return createRecord(creds, params as CreateRecordParams, context)
      case 'updateRecord':
        return updateRecord(creds, params as UpdateRecordParams, context)
      case 'listRecords':
        return listRecords(creds, params as ListRecordsParams, context)
      case 'getRecord':
        return getRecord(creds, params as GetRecordParams, context)
      case 'deleteRecord':
        return deleteRecord(creds, params as DeleteRecordParams, context)
      case 'listObjects':
        return listObjects(creds, params as ListObjectsParams, context)
      case 'listAttributes':
        return listAttributes(creds, params as ListAttributesParams, context)
      case 'createAttribute':
        return createAttribute(creds, params as CreateAttributeParams, context)
      case 'updateAttribute':
        return updateAttribute(creds, params as UpdateAttributeParams, context)
      case 'createNote':
        return createNote(creds, params as CreateNoteParams, context)
      case 'listNotes':
        return listNotes(creds, params as ListNotesParams, context)
      case 'deleteNote':
        return deleteNote(creds, params as DeleteNoteParams, context)
      default:
        throw new ToolingError('method_not_found', `Unknown Attio method: ${method}`, {
          integration: this.name,
          method,
          organizationId: context?.organizationId
        })
    }
  }

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