/**
 * List Objects - Attio API
 *
 * Lists all objects (people, companies, deals, custom) in the workspace.
 * GET /v2/objects
 *
 * Documentation: https://developers.attio.com/reference/get-objects
 */

import { ToolingError } from '../../../../../../types'
import { withRetry, createHttpError, DEFAULT_RETRY_POLICY } from '../../../../../../../../../platform/resilience'
import type { ExecutionContext } from '../../../../../../../base/types'
import type { AttioCredentials, ListObjectsParams, ListObjectsResult, AttioObjectsListResponse } from '../utils/types'

/**
 * List all objects in the Attio workspace
 *
 * @param credentials - Attio API credentials (apiKey)
 * @param _params - Empty parameters object (all objects are returned)
 * @param context - Execution context for logging
 * @returns List of objects with id, slug, singular/plural nouns, and createdAt
 * @throws ToolingError if API call fails
 *
 * @example
 * const result = await listObjects(
 *   { apiKey: 'xxx' },
 *   {},
 *   context
 * )
 * // result.objects = [{ id: '...', slug: 'people', ... }, ...]
 */
export async function listObjects(
  credentials: AttioCredentials,
  _params: ListObjectsParams,
  context?: ExecutionContext
): Promise<ListObjectsResult> {
  const { apiKey } = credentials

  // Validate credentials
  if (!apiKey) {
    throw new ToolingError('credentials_invalid', 'Missing Attio API key', {
      integration: 'attio',
      method: 'listObjects',
      organizationId: context?.organizationId
    })
  }

  // Build URL
  const url = 'https://api.attio.com/v2/objects'

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

      // Handle HTTP errors
      if (!response.ok) {
        throw await createHttpError(response, {
          integration: 'attio',
          method: 'listObjects',
          organizationId: context?.organizationId
        })
      }

      return (await response.json()) as AttioObjectsListResponse
    }, DEFAULT_RETRY_POLICY)

    // Log success
    if (context?.logger) {
      context.logger.info(
        `[AttioAdapter] Objects listed: objectCount=${data.data.length} executionId=${context.executionId}`
      )
    }

    // Transform response to clean format
    return {
      objects: data.data.map((obj) => ({
        id: obj.id.object_id,
        slug: obj.api_slug,
        singularNoun: obj.singular_noun,
        pluralNoun: obj.plural_noun,
        createdAt: obj.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 list Attio objects: ${(error as Error).message}`, {
      integration: 'attio',
      method: 'listObjects',
      organizationId: context?.organizationId
    })
  }
}
