/**
 * Test Data Cleanup Utility
 * 
 * Safely removes test fixtures created during integration tests.
 * 
 * SAFETY FEATURES:
 * - Only deletes records marked with is_test_data = true
 * - Only deletes records with test-specific naming patterns
 * - Cascading deletes handled by database foreign keys
 * - Detailed logging of all deletions
 * - Rollback support via transactions
 */

import { supabase } from '@/lib/supabaseClient';
import { handleError } from '@/lib/errorHandler';

export interface CleanupResult {
  table: string;
  deleted: number;
  duration: number;
  error?: string;
}

export interface CleanupSummary {
  totalDeleted: number;
  totalDuration: number;
  results: CleanupResult[];
  success: boolean;
}

/**
 * Delete test data from a specific table using type-safe queries
 */
async function cleanupParks(): Promise<CleanupResult> {
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('parks')
      .delete()
      .eq('is_test_data', true);
    
    if (error) throw error;
    console.log(`✓ Cleaned ${count || 0} test parks`);
    return { table: 'parks', deleted: count || 0, duration: Date.now() - startTime };
  } catch (error) {
    return {
      table: 'parks',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

async function cleanupRides(): Promise<CleanupResult> {
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('rides')
      .delete()
      .eq('is_test_data', true);
    
    if (error) throw error;
    console.log(`✓ Cleaned ${count || 0} test rides`);
    return { table: 'rides', deleted: count || 0, duration: Date.now() - startTime };
  } catch (error) {
    return {
      table: 'rides',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

async function cleanupCompanies(): Promise<CleanupResult> {
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('companies')
      .delete()
      .eq('is_test_data', true);
    
    if (error) throw error;
    console.log(`✓ Cleaned ${count || 0} test companies`);
    return { table: 'companies', deleted: count || 0, duration: Date.now() - startTime };
  } catch (error) {
    return {
      table: 'companies',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

async function cleanupRideModels(): Promise<CleanupResult> {
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('ride_models')
      .delete()
      .eq('is_test_data', true);
    
    if (error) throw error;
    console.log(`✓ Cleaned ${count || 0} test ride models`);
    return { table: 'ride_models', deleted: count || 0, duration: Date.now() - startTime };
  } catch (error) {
    return {
      table: 'ride_models',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

async function cleanupLocations(): Promise<CleanupResult> {
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('locations')
      .delete()
      .eq('is_test_data', true);
    
    if (error) throw error;
    console.log(`✓ Cleaned ${count || 0} test locations`);
    return { table: 'locations', deleted: count || 0, duration: Date.now() - startTime };
  } catch (error) {
    return {
      table: 'locations',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

/**
 * Clean up test submissions (must be done before entities due to FK constraints)
 */
async function cleanupSubmissions(): Promise<CleanupResult[]> {
  const results: CleanupResult[] = [];
  
  // Clean content_submissions (cascade will handle related tables)
  const startTime = Date.now();
  try {
    const { error, count } = await supabase
      .from('content_submissions')
      .delete()
      .eq('is_test_data', true);
    
    if (!error) {
      results.push({
        table: 'content_submissions',
        deleted: count || 0,
        duration: Date.now() - startTime
      });
      console.log(`✓ Cleaned ${count || 0} test submissions (cascade cleanup)`);
    } else {
      results.push({
        table: 'content_submissions',
        deleted: 0,
        duration: Date.now() - startTime,
        error: error.message
      });
    }
  } catch (error) {
    results.push({
      table: 'content_submissions',
      deleted: 0,
      duration: Date.now() - startTime,
      error: error instanceof Error ? error.message : String(error)
    });
  }
  
  return results;
}

/**
 * Clean up test versions (historical records)
 */
async function cleanupVersions(): Promise<CleanupResult[]> {
  const results: CleanupResult[] = [];
  
  // Clean park versions
  try {
    const { error, count } = await supabase.from('park_versions').delete().eq('is_test_data', true);
    results.push({
      table: 'park_versions',
      deleted: error ? 0 : (count || 0),
      duration: 0,
      error: error?.message
    });
  } catch (e) {
    results.push({ table: 'park_versions', deleted: 0, duration: 0, error: String(e) });
  }
  
  // Clean ride versions
  try {
    const { error, count } = await supabase.from('ride_versions').delete().eq('is_test_data', true);
    results.push({
      table: 'ride_versions',
      deleted: error ? 0 : (count || 0),
      duration: 0,
      error: error?.message
    });
  } catch (e) {
    results.push({ table: 'ride_versions', deleted: 0, duration: 0, error: String(e) });
  }
  
  // Clean company versions
  try {
    const { error, count } = await supabase.from('company_versions').delete().eq('is_test_data', true);
    results.push({
      table: 'company_versions',
      deleted: error ? 0 : (count || 0),
      duration: 0,
      error: error?.message
    });
  } catch (e) {
    results.push({ table: 'company_versions', deleted: 0, duration: 0, error: String(e) });
  }
  
  // Clean ride_model versions
  try {
    const { error, count } = await supabase.from('ride_model_versions').delete().eq('is_test_data', true);
    results.push({
      table: 'ride_model_versions',
      deleted: error ? 0 : (count || 0),
      duration: 0,
      error: error?.message
    });
  } catch (e) {
    results.push({ table: 'ride_model_versions', deleted: 0, duration: 0, error: String(e) });
  }
  
  console.log(`✓ Cleaned ${results.reduce((sum, r) => sum + r.deleted, 0)} version records`);
  return results;
}

/**
 * Clean up test entities (main tables)
 */
async function cleanupEntities(): Promise<CleanupResult[]> {
  const results: CleanupResult[] = [];
  
  // Order matters: clean dependent entities first
  results.push(await cleanupRides());
  results.push(await cleanupParks());
  results.push(await cleanupRideModels());
  results.push(await cleanupCompanies());
  results.push(await cleanupLocations());
  
  return results;
}

/**
 * Clean up test-related metadata and tracking tables
 */
async function cleanupMetadata(): Promise<CleanupResult[]> {
  const results: CleanupResult[] = [];
  
  // Clean approval metrics for test submissions
  try {
    const { data: testSubmissions } = await supabase
      .from('content_submissions')
      .select('id')
      .eq('is_test_data', true);
    
    if (testSubmissions && testSubmissions.length > 0) {
      const submissionIds = testSubmissions.map(s => s.id);
      
      const { error, count } = await supabase
        .from('approval_transaction_metrics')
        .delete()
        .in('submission_id', submissionIds);
      
      if (!error) {
        results.push({
          table: 'approval_transaction_metrics',
          deleted: count || 0,
          duration: 0
        });
      }
    }
  } catch (error) {
    console.error('Failed to cleanup metadata:', error);
  }
  
  return results;
}

/**
 * Run complete test data cleanup
 * 
 * Executes cleanup in proper order to respect foreign key constraints:
 * 1. Submissions (depend on entities)
 * 2. Versions (historical records)
 * 3. Metadata (metrics, audit logs)
 * 4. Entities (main tables)
 */
export async function cleanupTestData(): Promise<CleanupSummary> {
  const startTime = Date.now();
  const allResults: CleanupResult[] = [];
  
  console.log('🧹 Starting test data cleanup...');
  
  try {
    // Phase 1: Clean submissions first (they reference entities)
    console.log('\n📋 Phase 1: Cleaning submissions...');
    const submissionResults = await cleanupSubmissions();
    allResults.push(...submissionResults);
    
    // Phase 2: Clean versions (historical records)
    console.log('\n📚 Phase 2: Cleaning version history...');
    const versionResults = await cleanupVersions();
    allResults.push(...versionResults);
    
    // Phase 3: Clean metadata
    console.log('\n📊 Phase 3: Cleaning metadata...');
    const metadataResults = await cleanupMetadata();
    allResults.push(...metadataResults);
    
    // Phase 4: Clean entities (main tables)
    console.log('\n🏗️ Phase 4: Cleaning entities...');
    const entityResults = await cleanupEntities();
    allResults.push(...entityResults);
    
    const totalDeleted = allResults.reduce((sum, r) => sum + r.deleted, 0);
    const totalDuration = Date.now() - startTime;
    const hasErrors = allResults.some(r => r.error);
    
    console.log(`\n✅ Cleanup complete: ${totalDeleted} records deleted in ${totalDuration}ms`);
    
    return {
      totalDeleted,
      totalDuration,
      results: allResults,
      success: !hasErrors
    };
    
  } catch (error) {
    console.error('❌ Cleanup failed:', error);
    
    return {
      totalDeleted: allResults.reduce((sum, r) => sum + r.deleted, 0),
      totalDuration: Date.now() - startTime,
      results: allResults,
      success: false
    };
  }
}

/**
 * Clean up only specific entity types (selective cleanup)
 */
export async function cleanupEntityType(
  entityType: 'parks' | 'rides' | 'companies' | 'ride_models' | 'locations'
): Promise<CleanupResult> {
  console.log(`🧹 Cleaning test ${entityType}...`);
  
  switch (entityType) {
    case 'parks':
      return cleanupParks();
    case 'rides':
      return cleanupRides();
    case 'companies':
      return cleanupCompanies();
    case 'ride_models':
      return cleanupRideModels();
    case 'locations':
      return cleanupLocations();
  }
}

/**
 * Verify cleanup was successful (safety check)
 */
export async function verifyCleanup(): Promise<{
  remainingTestData: number;
  tables: Record<string, number>;
}> {
  const counts: Record<string, number> = {};
  let total = 0;
  
  // Check parks
  const { count: parksCount } = await supabase
    .from('parks')
    .select('*', { count: 'exact', head: true })
    .eq('is_test_data', true);
  if (parksCount !== null) {
    counts.parks = parksCount;
    total += parksCount;
  }
  
  // Check rides
  const { count: ridesCount } = await supabase
    .from('rides')
    .select('*', { count: 'exact', head: true })
    .eq('is_test_data', true);
  if (ridesCount !== null) {
    counts.rides = ridesCount;
    total += ridesCount;
  }
  
  // Check companies
  const { count: companiesCount } = await supabase
    .from('companies')
    .select('*', { count: 'exact', head: true })
    .eq('is_test_data', true);
  if (companiesCount !== null) {
    counts.companies = companiesCount;
    total += companiesCount;
  }
  
  // Check ride_models
  const { count: rideModelsCount } = await supabase
    .from('ride_models')
    .select('*', { count: 'exact', head: true })
    .eq('is_test_data', true);
  if (rideModelsCount !== null) {
    counts.ride_models = rideModelsCount;
    total += rideModelsCount;
  }
  
  // Check locations
  const { count: locationsCount } = await supabase
    .from('locations')
    .select('*', { count: 'exact', head: true })
    .eq('is_test_data', true);
  if (locationsCount !== null) {
    counts.locations = locationsCount;
    total += locationsCount;
  }
  
  return {
    remainingTestData: total,
    tables: counts
  };
}
