/**
 * Test script for full sync with Autotask
 * Run with: npx tsx dev/test-full-sync.ts
 * 
 * This script tests the full sync functionality with a small dataset
 * by limiting the number of records fetched from Autotask.
 */

import dotenv from 'dotenv';
import path from 'path';

// Load environment variables from .env.local FIRST
dotenv.config({ path: path.resolve(__dirname, '../.env.local') });

import { AutotaskClient } from '../lib/services/autotask-client';
import { createSyncService } from '../lib/services/sync-service';
import { EntityType } from '../lib/types/sync';
import postgresClient from '../lib/services/postgres-client';

async function testFullSync() {
  console.log('🔍 Testing Full Sync with Autotask\n');
  
  // Check environment variables
  console.log('Environment Configuration:');
  console.log('  AUTOTASK_API_URL:', process.env.AUTOTASK_API_URL);
  console.log('  AUTOTASK_USERNAME:', process.env.AUTOTASK_USERNAME ? '[SET]' : '[NOT SET]');
  console.log('  AUTOTASK_SECRET:', process.env.AUTOTASK_SECRET ? '[SET]' : '[NOT SET]');
  console.log('  AUTOTASK_API_INTEGRATION_CODE:', process.env.AUTOTASK_API_INTEGRATION_CODE ? '[SET]' : '[NOT SET]');
  console.log('  POSTGRES_HOST:', process.env.POSTGRES_HOST);
  console.log('  POSTGRES_DB:', process.env.POSTGRES_DB);
  console.log();

  // Validate required environment variables
  if (!process.env.AUTOTASK_API_URL || !process.env.AUTOTASK_USERNAME || 
      !process.env.AUTOTASK_SECRET || !process.env.AUTOTASK_API_INTEGRATION_CODE) {
    console.error('❌ Missing required Autotask environment variables');
    console.error('Please ensure .env.local contains:');
    console.error('  - AUTOTASK_API_URL');
    console.error('  - AUTOTASK_USERNAME');
    console.error('  - AUTOTASK_SECRET');
    console.error('  - AUTOTASK_API_INTEGRATION_CODE');
    process.exit(1);
  }

  try {
    // Test 1: Database connection
    console.log('Test 1: Verify database connection');
    const dbConnected = await postgresClient.testConnection();
    if (!dbConnected) {
      console.error('❌ Database connection failed');
      process.exit(1);
    }
    console.log('✅ Database connection successful\n');

    // Test 2: Create Autotask client
    console.log('Test 2: Initialize Autotask client');
    const autotaskClient = new AutotaskClient({
      apiUrl: process.env.AUTOTASK_API_URL!,
      username: process.env.AUTOTASK_USERNAME!,
      password: process.env.AUTOTASK_SECRET!,
      apiIntegrationCode: process.env.AUTOTASK_API_INTEGRATION_CODE!,
    });
    console.log('✅ Autotask client initialized\n');

    // Test 3: Test Autotask API connection with a simple query
    console.log('Test 3: Test Autotask API connection');
    try {
      // Try to fetch a small number of companies to test the connection
      const testCompanies = await autotaskClient.queryEntity('Companies', {
        filter: [{ field: 'isActive', op: 'eq', value: true }],
        maxRecords: 5,
      });
      console.log(`✅ Autotask API connection successful (fetched ${testCompanies.length} test companies)\n`);
    } catch (error) {
      console.error('❌ Autotask API connection failed:', error);
      console.error('\nPlease verify:');
      console.error('  1. API credentials are correct');
      console.error('  2. API integration code is valid');
      console.error('  3. Network connectivity to Autotask API');
      process.exit(1);
    }

    // Test 4: Create sync service
    console.log('Test 4: Initialize sync service');
    const syncService = createSyncService(autotaskClient);
    console.log('✅ Sync service initialized\n');

    // Test 5: Sync a single entity (Companies) as a small test
    console.log('Test 5: Sync Companies entity (limited dataset)');
    console.log('Note: This will sync only active companies to limit data volume\n');
    
    const startTime = Date.now();
    try {
      const result = await syncService.syncEntities(
        [EntityType.COMPANIES],
        undefined,
        'test-script'
      );

      const duration = Date.now() - startTime;
      
      console.log('\n=== SYNC RESULTS ===');
      console.log(`Sync ID: ${result.syncId}`);
      console.log(`Status: ${result.status}`);
      console.log(`Duration: ${duration}ms`);
      console.log(`\nRecords:`);
      console.log(`  Added: ${result.totalRecordsAdded}`);
      console.log(`  Updated: ${result.totalRecordsUpdated}`);
      console.log(`  Deleted: ${result.totalRecordsDeleted}`);
      
      if (result.errors && result.errors.length > 0) {
        console.log(`\nErrors:`);
        result.errors.forEach(error => console.log(`  - ${error}`));
      }
      
      console.log('\n=== ENTITY DETAILS ===');
      result.entities.forEach(entity => {
        const status = entity.success ? '✅' : '❌';
        console.log(`${status} ${entity.entityType}:`);
        console.log(`   Added: ${entity.recordsAdded}, Updated: ${entity.recordsUpdated}, Deleted: ${entity.recordsDeleted}`);
        console.log(`   Duration: ${entity.duration}ms`);
        if (entity.error) {
          console.log(`   Error: ${entity.error}`);
        }
      });

      if (result.status === 'completed') {
        console.log('\n✅ Companies sync completed successfully!');
      } else {
        console.log('\n⚠️  Companies sync completed with errors');
      }
    } catch (error) {
      console.error('\n❌ Sync failed:', error);
      throw error;
    }

    // Test 6: Verify data in database
    console.log('\nTest 6: Verify synced data in database');
    const companyCount = await postgresClient.count('companies', { is_deleted: false });
    console.log(`✅ Found ${companyCount} companies in database\n`);

    // Test 7: Check sync history
    console.log('Test 7: Check sync history');
    const syncHistory = await syncService.getSyncHistory(5, EntityType.COMPANIES);
    console.log(`✅ Found ${syncHistory.length} sync history records`);
    if (syncHistory.length > 0) {
      const latest = syncHistory[0];
      console.log(`   Latest sync:`);
      console.log(`     Entity: ${latest.entity_type}`);
      console.log(`     Status: ${latest.status}`);
      console.log(`     Started: ${latest.started_at}`);
      console.log(`     Completed: ${latest.completed_at}`);
      console.log(`     Records: +${latest.records_added} ~${latest.records_updated} -${latest.records_deleted}`);
    }
    console.log();

    // Optional: Test 8: Sync multiple entities (commented out to keep test small)
    /*
    console.log('Test 8: Sync multiple entities');
    const multiResult = await syncService.syncEntities(
      [EntityType.COMPANIES, EntityType.RESOURCES, EntityType.STATUSES],
      undefined,
      'test-script-multi'
    );
    console.log(`✅ Multi-entity sync completed: ${multiResult.status}`);
    console.log(`   Total records: +${multiResult.totalRecordsAdded} ~${multiResult.totalRecordsUpdated} -${multiResult.totalRecordsDeleted}\n`);
    */

    console.log('🎉 All sync tests passed successfully!');
    console.log('\n=== SUMMARY ===');
    console.log('✅ Database connection working');
    console.log('✅ Autotask API connection working');
    console.log('✅ Sync service operational');
    console.log('✅ Entity sync working');
    console.log('✅ Data persisted to database');
    console.log('✅ Sync history tracking working');

  } catch (error) {
    console.error('\n❌ Test failed with error:', error);
    if (error instanceof Error) {
      console.error('Stack trace:', error.stack);
    }
    process.exit(1);
  } finally {
    // Close database connection
    await postgresClient.close();
    console.log('\n🔌 Database connection closed');
  }
}

// Run the tests
testFullSync()
  .then(() => {
    console.log('\n✅ Test script completed successfully');
    process.exit(0);
  })
  .catch((error) => {
    console.error('\n❌ Test script failed:', error);
    process.exit(1);
  });
