/**
 * Attio List Records - Native Fetch Implementation
 *
 * Queries/lists records from an Attio object using native Node.js fetch API.
 * Supports filtering, sorting, and pagination for all object types.
 *
 * API Endpoint: POST /v2/objects/{object}/records/query
 * Documentation: https://developers.attio.com/reference/list-records
 *
 * Note: This is a POST endpoint (not GET) to support complex filter and sort criteria.
 */

import { ToolingError } from '../../../../../../types'
import { withRetry, createHttpError, DEFAULT_RETRY_POLICY } from '../../../../../../../../../platform/resilience'
import type { ExecutionContext } from '../../../../../../../base/types'
import type { AttioCredentials, QueryRecordsParams, QueryRecordsResult, AttioQueryResponse } from '../utils/types'

/**
 * Query/list records from an Attio object
 *
 * Uses native Node.js fetch API with retry logic for resilience.
 * Supports advanced filtering, sorting, and offset-based pagination.
 *
 * Filter operators supported:
 * - $eq, $ne (equality)
 * - $gt, $gte, $lt, $lte (comparisons)
 * - $contains, $starts_with (string matching)
 * - $and, $or (logical operators)
 *
 * @param credentials - Attio API credentials (Bearer token)
 * @param params - Object type, filter, sorts, limit, offset
 * @param context - Execution context for logging
 * @returns List of records with pagination info
 * @throws ToolingError on API errors
 */
export async function listRecords(
  credentials: AttioCredentials,
  params: QueryRecordsParams,
  context?: ExecutionContext
): Promise<QueryRecordsResult> {
  const { object, filter, sorts, limit = 500, offset = 0 } = params
  const { apiKey } = credentials

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

  // Validate parameters
  if (!object) {
    throw new ToolingError('validation_error', 'Missing required parameter: object', {
      integration: 'attio',
      method: 'listRecords',
      params: { object }
    })
  }

  // Build API URL
  const url = `https://api.attio.com/v2/objects/${object}/records/query`

  // Build request body
  const requestBody: {
    filter?: typeof filter
    sorts?: typeof sorts
    limit: number
    offset: number
  } = {
    limit,
    offset
  }

  // Only include filter and sorts if provided
  if (filter) {
    requestBody.filter = filter
  }

  if (sorts && sorts.length > 0) {
    requestBody.sorts = sorts
  }

  try {
    // Execute with retry logic
    const data = await withRetry(async () => {
      const response = await fetch(url, {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${apiKey}`,
          'Content-Type': 'application/json',
          Accept: 'application/json'
        },
        body: JSON.stringify(requestBody)
      })

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

      // Parse response
      const responseData = (await response.json()) as AttioQueryResponse

      // Validate response structure
      if (!responseData.data || !Array.isArray(responseData.data)) {
        throw new ToolingError('api_error', 'Invalid response format: expected data array', {
          integration: 'attio',
          method: 'listRecords',
          responseType: typeof responseData.data
        })
      }

      return responseData
    }, DEFAULT_RETRY_POLICY)

    // Determine if more records are available
    // Attio uses offset-based pagination: hasMore = returned records count equals limit
    const hasMore = data.data.length === limit

    // Log success
    if (context?.logger) {
      context.logger.info(
        `[AttioAdapter] Records listed: object=${object} recordCount=${data.data.length} limit=${limit} offset=${offset} hasMore=${hasMore} executionId=${context.executionId}`
      )
    }

    // Transform to result format
    return {
      records: data.data.map((record) => ({
        id: record.id.record_id,
        values: record.values,
        createdAt: record.created_at,
        webUrl: record.web_url
      })),
      hasMore
    }
  } 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 records: ${(error as Error).message}`, {
      integration: 'attio',
      method: 'listRecords',
      organizationId: context?.organizationId,
      params: { object, filter, sorts, limit, offset }
    })
  }
}
