import { describe as _describe, it, expect, beforeAll, afterAll, vi } from 'vitest'

// Attio integration not in use; suite skipped per project decision (2026-04-29).
const describe = _describe.skip
import { AttioAdapter } from '../attio-adapter'
import type { ExecutionContext } from '../../../../../../base/types'
import { createClient } from '@supabase/supabase-js'
import type { Database } from '../../../../../../../../supabase/database.types'
import { decryptCredentialValue } from '../../../../../../../../auth/multi-tenancy/credentials/server/service'
import type {
  CreateRecordResult,
  UpdateRecordResult,
  GetRecordResult,
  QueryRecordsResult,
  DeleteRecordResult
} from '../fetch/utils/types'

/**
 * Comprehensive CRUD Integration Test Suite for Attio
 *
 * Tests the complete lifecycle:
 * 1. List records (people)
 * 2. Create person record
 * 3. Get record by ID
 * 4. Update record
 * 5. List records with filters
 * 6. Error handling
 *
 * Prerequisites:
 * - Supabase database with credentials table
 * - Credential 'elevasis-attio' with valid Attio API Key
 * - Organization ID: f9aa5a56-8c13-4cd1-9161-8827ae7b452b
 * - SUPABASE_URL and SUPABASE_SERVICE_KEY env vars set
 * - Attio workspace accessible with provided credentials
 *
 * Run: pnpm test attio-crud.integration.test.ts
 */

// Attio integration currently unused -- tests skipped unconditionally.
describe.skip('Attio CRUD Integration Tests', () => {
  const adapter = new AttioAdapter()
  const organizationId = 'f9aa5a56-8c13-4cd1-9161-8827ae7b452b'
  const credentialName = 'elevasis-attio'

  const context: ExecutionContext = {
    organizationId,
    executionId: 'crud-integration-test',
    resourceId: 'crud-test-agent',
    resourceType: 'agent',
    logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), child: vi.fn().mockReturnThis() }
  }

  let supabase: ReturnType<typeof createClient<Database>>
  let credentials: Record<string, unknown>
  let createdRecordId: string

  beforeAll(async () => {
    console.log('\n=== Attio CRUD Integration Test Suite ===')
    console.log(`Organization: ${organizationId}`)
    console.log(`Credential: ${credentialName}\n`)

    // Initialize Supabase
    supabase = createClient<Database>(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)

    // Fetch credential from database
    const { data: credRow, error } = await supabase
      .from('credentials')
      .select('encrypted_value')
      .eq('organization_id', organizationId)
      .eq('name', credentialName)
      .single()

    if (error || !credRow) {
      throw new Error(`Credential '${credentialName}' not found for org ${organizationId}. Error: ${error?.message}`)
    }

    // Decrypt credentials
    credentials = decryptCredentialValue(credRow.encrypted_value)

    console.log('✓ Credentials loaded and decrypted')
    console.log(`✓ API Key present: ${!!credentials.apiKey}`)

    // Validate credentials
    const isValid = adapter.validateCredentials(credentials)
    if (!isValid) {
      throw new Error('Credential validation failed')
    }
    console.log('✓ Credentials validated')
    console.log('\n✓ Ready to run tests')
  })

  it('should list people records', { timeout: 30000 }, async () => {
    console.log('\n[Test] List people records')

    const result = (await adapter.call(
      'listRecords',
      {
        object: 'people',
        limit: 10,
        offset: 0
      },
      credentials,
      context
    )) as QueryRecordsResult

    console.log(`✓ Listed ${result.records.length} people`)

    expect(result).toBeDefined()
    expect(result.records).toBeInstanceOf(Array)
    expect(result.hasMore).toBeDefined()
  })

  it('should create a person record', async () => {
    console.log('\n[Test] Create person record')

    const testEmail = `test-${Date.now()}@example.com`

    const result = (await adapter.call(
      'createRecord',
      {
        object: 'people',
        values: {
          name: {
            first_name: 'Test',
            last_name: 'User',
            full_name: 'Test User'
          },
          email_addresses: [
            {
              email_address: testEmail
            }
          ]
        }
      },
      credentials,
      context
    )) as CreateRecordResult

    console.log(`✓ Created person: ${result.recordId}`)

    expect(result).toBeDefined()
    expect(result.recordId).toBeDefined()
    expect(result.success).toBe(true)

    // Store for later tests
    createdRecordId = result.recordId
  })

  it('should get the created record by ID', async () => {
    console.log('\n[Test] Get record by ID')

    expect(createdRecordId).toBeDefined()

    const result = (await adapter.call(
      'getRecord',
      {
        object: 'people',
        recordId: createdRecordId
      },
      credentials,
      context
    )) as GetRecordResult

    console.log(`✓ Retrieved record: ${result.id}`)

    expect(result).toBeDefined()
    expect(result.id).toBe(createdRecordId)
    expect(result.values).toBeDefined()
    expect(result.createdAt).toBeDefined()
  })

  it('should update the created record', async () => {
    console.log('\n[Test] Update record')

    expect(createdRecordId).toBeDefined()

    const result = (await adapter.call(
      'updateRecord',
      {
        object: 'people',
        recordId: createdRecordId,
        values: {
          description: 'Updated via integration test'
        }
      },
      credentials,
      context
    )) as UpdateRecordResult

    console.log(`✓ Updated record: ${result.recordId}`)

    expect(result).toBeDefined()
    expect(result.recordId).toBe(createdRecordId)
    expect(result.success).toBe(true)
  })

  it('should list records with custom limit', async () => {
    console.log('\n[Test] List records with custom limit')

    const result = (await adapter.call(
      'listRecords',
      {
        object: 'people',
        limit: 5,
        offset: 0
      },
      credentials,
      context
    )) as QueryRecordsResult

    console.log(`✓ Listed ${result.records.length} people (limit: 5)`)

    expect(result).toBeDefined()
    expect(result.records).toBeInstanceOf(Array)
    expect(result.records.length).toBeLessThanOrEqual(5)
  })

  it('should list records with pagination', { timeout: 30000 }, async () => {
    console.log('\n[Test] List records with pagination')

    const page1 = (await adapter.call(
      'listRecords',
      {
        object: 'people',
        limit: 2,
        offset: 0
      },
      credentials,
      context
    )) as QueryRecordsResult

    const page2 = (await adapter.call(
      'listRecords',
      {
        object: 'people',
        limit: 2,
        offset: 2
      },
      credentials,
      context
    )) as QueryRecordsResult

    console.log(`✓ Page 1: ${page1.records.length} records`)
    console.log(`✓ Page 2: ${page2.records.length} records`)

    expect(page1).toBeDefined()
    expect(page2).toBeDefined()
    expect(page1.records).toBeInstanceOf(Array)
    expect(page2.records).toBeInstanceOf(Array)
  })

  it('should list records with sorting', async () => {
    console.log('\n[Test] List records with sorting')

    const result = (await adapter.call(
      'listRecords',
      {
        object: 'people',
        sorts: [
          {
            attribute: 'name',
            field: 'last_name',
            direction: 'asc'
          }
        ],
        limit: 10
      },
      credentials,
      context
    )) as QueryRecordsResult

    console.log(`✓ Listed ${result.records.length} people (sorted by name)`)

    expect(result).toBeDefined()
    expect(result.records).toBeInstanceOf(Array)
  })

  it('should handle invalid record ID gracefully', async () => {
    console.log('\n[Test] Handle invalid record ID')

    await expect(
      adapter.call(
        'getRecord',
        {
          object: 'people',
          recordId: 'invalid-uuid-12345'
        },
        credentials,
        context
      )
    ).rejects.toThrow()

    console.log('✓ Invalid record ID rejected as expected')
  })

  it('should handle invalid credentials gracefully', async () => {
    console.log('\n[Test] Handle invalid credentials')

    const invalidCreds = { apiKey: 'invalid-key-12345' }

    await expect(
      adapter.call(
        'listRecords',
        {
          object: 'people',
          limit: 10
        },
        invalidCreds,
        context
      )
    ).rejects.toThrow()

    console.log('✓ Invalid credentials rejected as expected')
  })

  it('should work with companies object type', async () => {
    console.log('\n[Test] List companies')

    const result = (await adapter.call(
      'listRecords',
      {
        object: 'companies',
        limit: 5
      },
      credentials,
      context
    )) as QueryRecordsResult

    console.log(`✓ Listed ${result.records.length} companies`)

    expect(result).toBeDefined()
    expect(result.records).toBeInstanceOf(Array)
  })

  afterAll(async () => {
    // Clean up test data
    if (createdRecordId) {
      console.log('\n=== Cleanup ===')
      console.log(`Deleting test record: ${createdRecordId}`)

      try {
        const result = (await adapter.call(
          'deleteRecord',
          {
            object: 'people',
            recordId: createdRecordId
          },
          credentials,
          context
        )) as DeleteRecordResult

        if (result.success) {
          console.log(`✓ Test record deleted: ${createdRecordId}`)
        } else {
          console.log(`⚠️  Delete returned success=false for record: ${createdRecordId}`)
        }
      } catch (error) {
        console.warn('⚠️  Cleanup failed:', error)
        console.warn(`   Manual cleanup may be needed for record: ${createdRecordId}`)
      }
    }
  })
})
