import { supabase } from '@/integrations/supabase/client';
import type { Database } from '@/integrations/supabase/types';

type TableName = keyof Database['public']['Tables'];

/**
 * TestDataTracker - Manages test data lifecycle for integration tests
 * 
 * Tracks all created test entities and ensures proper cleanup in dependency order.
 * All tracked entities are marked with is_test_data=true for easy identification.
 */
export class TestDataTracker {
  private entities = new Map<string, Set<string>>();

  /**
   * Track an entity for cleanup
   * @param table - Database table name
   * @param id - Entity ID
   */
  track(table: string, id: string): void {
    if (!this.entities.has(table)) {
      this.entities.set(table, new Set());
    }
    this.entities.get(table)!.add(id);
  }

  /**
   * Track multiple entities at once
   * @param table - Database table name
   * @param ids - Array of entity IDs
   */
  trackMany(table: string, ids: string[]): void {
    ids.forEach(id => this.track(table, id));
  }

  /**
   * Get all tracked entity IDs for a specific table
   * @param table - Database table name
   * @returns Array of tracked IDs
   */
  getTracked(table: string): string[] {
    return Array.from(this.entities.get(table) || []);
  }

  /**
   * Cleanup all tracked test data in proper dependency order
   * Deletes children first, then parents to avoid foreign key violations
   */
  async cleanup(): Promise<void> {
    // Define deletion order (children first, parents last)
    const deletionOrder: TableName[] = [
      'reviews',
      'photos',
      'submission_items',
      'content_submissions',
      'ride_versions',
      'park_versions',
      'company_versions',
      'ride_model_versions',
      'rides',
      'parks',
      'ride_models',
      'companies',
      'test_data_registry'
    ];

    const errors: Array<{ table: string; error: any }> = [];

    for (const table of deletionOrder) {
      const ids = this.getTracked(table);
      if (ids.length === 0) continue;

      try {
        const { error } = await supabase
          .from(table as any)
          .delete()
          .in('id', ids);

        if (error) {
          errors.push({ table, error });
          console.warn(`Failed to cleanup ${table}:`, error);
        }
      } catch (err) {
        errors.push({ table, error: err });
        console.warn(`Exception cleaning up ${table}:`, err);
      }
    }

    // Clear tracking after cleanup attempt
    this.entities.clear();

    if (errors.length > 0) {
      console.warn(`Cleanup completed with ${errors.length} errors:`, errors);
    }
  }

  /**
   * Verify that all tracked test data has been cleaned up
   * @returns Array of remaining test data items
   */
  async verifyCleanup(): Promise<Array<{ table: string; count: number }>> {
    const tables: TableName[] = [
      'parks', 'rides', 'companies', 'ride_models',
      'content_submissions', 'submission_items',
      'park_versions', 'ride_versions', 'company_versions', 'ride_model_versions',
      'photos', 'reviews', 'test_data_registry'
    ];

    const remaining: Array<{ table: string; count: number }> = [];

    for (const table of tables) {
      try {
        const { count, error } = await supabase
          .from(table as any)
          .select('*', { count: 'exact', head: true })
          .eq('is_test_data', true);

        if (error) {
          console.warn(`Failed to check ${table}:`, error);
          continue;
        }

        if (count && count > 0) {
          remaining.push({ table, count });
        }
      } catch (err) {
        console.warn(`Exception checking ${table}:`, err);
      }
    }

    return remaining;
  }

  /**
   * Bulk delete all test data from the database (emergency cleanup)
   * WARNING: This deletes ALL data marked with is_test_data=true
   */
  static async bulkCleanupAllTestData(): Promise<{ deleted: number; errors: number }> {
    const tables: TableName[] = [
      'reviews', 'photos', 'submission_items', 'content_submissions',
      'ride_versions', 'park_versions', 'company_versions', 'ride_model_versions',
      'rides', 'parks', 'ride_models', 'companies', 'test_data_registry'
    ];

    let totalDeleted = 0;
    let totalErrors = 0;

    for (const table of tables) {
      try {
        const { error, data } = await supabase
          .from(table as any)
          .delete()
          .eq('is_test_data', true)
          .select('id');

        if (error) {
          console.warn(`Failed to bulk delete from ${table}:`, error);
          totalErrors++;
        } else if (data) {
          totalDeleted += data.length;
        }
      } catch (err) {
        console.warn(`Exception bulk deleting from ${table}:`, err);
        totalErrors++;
      }
    }

    return { deleted: totalDeleted, errors: totalErrors };
  }

  /**
   * Get summary of tracked entities
   */
  getSummary(): Record<string, number> {
    const summary: Record<string, number> = {};
    this.entities.forEach((ids, table) => {
      summary[table] = ids.size;
    });
    return summary;
  }
}
