/**
 * Performance & Scalability Integration Tests
 * 
 * Tests for system performance under various conditions.
 */

import { supabase } from '@/integrations/supabase/client';
import type { TestSuite, TestResult } from '../testRunner';
import { TestDataTracker } from '../TestDataTracker';

export const performanceTestSuite: TestSuite = {
  id: 'performance',
  name: 'Performance & Scalability',
  description: 'Tests for system performance and query efficiency',
  tests: [
    {
      id: 'perf-001',
      name: 'Entity Query Performance',
      description: 'Measures query performance for entity lists',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();

        try {
          // Test parks query performance
          const parksStart = Date.now();
          const { data: parks, error: parksError } = await supabase
            .from('parks')
            .select('id, name, slug, park_type, status')
            .limit(50);

          const parksDuration = Date.now() - parksStart;

          if (parksError) throw new Error(`Parks query failed: ${parksError.message}`);

          // Test rides query performance
          const ridesStart = Date.now();
          const { data: rides, error: ridesError } = await supabase
            .from('rides')
            .select('id, name, slug, category, status, park_id')
            .limit(50);

          const ridesDuration = Date.now() - ridesStart;

          if (ridesError) throw new Error(`Rides query failed: ${ridesError.message}`);

          // Test companies query performance
          const companiesStart = Date.now();
          const { data: companies, error: companiesError } = await supabase
            .from('companies')
            .select('id, name, slug, company_type')
            .limit(50);

          const companiesDuration = Date.now() - companiesStart;

          if (companiesError) throw new Error(`Companies query failed: ${companiesError.message}`);

          // Set performance thresholds (in milliseconds)
          const threshold = 1000; // 1 second
          const warnings: string[] = [];

          if (parksDuration > threshold) {
            warnings.push(`Parks query slow: ${parksDuration}ms`);
          }
          if (ridesDuration > threshold) {
            warnings.push(`Rides query slow: ${ridesDuration}ms`);
          }
          if (companiesDuration > threshold) {
            warnings.push(`Companies query slow: ${companiesDuration}ms`);
          }

          const totalDuration = Date.now() - startTime;

          return {
            id: 'perf-001',
            name: 'Entity Query Performance',
            suite: 'Performance & Scalability',
            status: warnings.length === 0 ? 'pass' : 'fail',
            duration: totalDuration,
            timestamp: new Date().toISOString(),
            error: warnings.length > 0 ? warnings.join('; ') : undefined,
            details: {
              parksDuration,
              ridesDuration,
              companiesDuration,
              threshold,
              parksCount: parks?.length || 0,
              ridesCount: rides?.length || 0,
              companiesCount: companies?.length || 0
            }
          };

        } catch (error) {
          return {
            id: 'perf-001',
            name: 'Entity Query Performance',
            suite: 'Performance & Scalability',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        }
      }
    },
    {
      id: 'perf-002',
      name: 'Version History Query Performance',
      description: 'Measures performance of version history queries',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();
        let parkId: string | null = null;

        try {
          // Create test park
          const parkSlug = `test-park-perf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
          const { data: park, error: parkError } = await supabase
            .from('parks')
            .insert({
              name: 'Test Park Performance',
              slug: parkSlug,
              park_type: 'theme_park',
              status: 'operating',
              is_test_data: true
            })
            .select('id')
            .single();

          if (parkError) throw parkError;
          parkId = park.id;
          tracker.track('parks', parkId);

          // Create multiple versions (updates)
          for (let i = 0; i < 10; i++) {
            await supabase
              .from('parks')
              .update({ description: `Version ${i + 1}` })
              .eq('id', parkId);
            
            // Small delay to ensure versions are created
            await new Promise(resolve => setTimeout(resolve, 50));
          }

          // Measure version history query
          const versionStart = Date.now();
          const { data: versions, error: versionError } = await supabase
            .from('park_versions')
            .select('version_id, version_number, change_type, created_at')
            .eq('park_id', parkId)
            .order('version_number', { ascending: false });

          const versionDuration = Date.now() - versionStart;

          if (versionError) throw new Error(`Version query failed: ${versionError.message}`);

          // Performance threshold: 500ms for version history
          const threshold = 500;
          const isSlow = versionDuration > threshold;

          const totalDuration = Date.now() - startTime;

          return {
            id: 'perf-002',
            name: 'Version History Query Performance',
            suite: 'Performance & Scalability',
            status: isSlow ? 'fail' : 'pass',
            duration: totalDuration,
            timestamp: new Date().toISOString(),
            error: isSlow ? `Version query took ${versionDuration}ms (threshold: ${threshold}ms)` : undefined,
            details: {
              versionDuration,
              threshold,
              versionsFound: versions?.length || 0,
              isSlow
            }
          };

        } catch (error) {
          return {
            id: 'perf-002',
            name: 'Version History Query Performance',
            suite: 'Performance & Scalability',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          await tracker.cleanup();
          const remaining = await tracker.verifyCleanup();
          if (remaining.length > 0) {
            console.warn('perf-002 cleanup incomplete:', remaining);
          }
        }
      }
    },
    {
      id: 'perf-003',
      name: 'Database Function Performance',
      description: 'Measures performance of database functions',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();

        try {
          const { data: userData } = await supabase.auth.getUser();
          if (!userData.user) throw new Error('No authenticated user');

          // Test is_moderator function performance
          const modStart = Date.now();
          const { data: isMod, error: modError } = await supabase
            .rpc('is_moderator', {
              _user_id: userData.user.id
            });

          const modDuration = Date.now() - modStart;

          if (modError) throw modError;

          // Test is_user_banned function performance
          const banStart = Date.now();
          const { data: isBanned, error: banError } = await supabase
            .rpc('is_user_banned', {
              _user_id: userData.user.id
            });

          const banDuration = Date.now() - banStart;

          if (banError) throw banError;

          // Performance threshold: 200ms for simple functions
          const threshold = 200;
          const warnings: string[] = [];

          if (modDuration > threshold) {
            warnings.push(`is_moderator slow: ${modDuration}ms`);
          }
          if (banDuration > threshold) {
            warnings.push(`is_user_banned slow: ${banDuration}ms`);
          }

          const totalDuration = Date.now() - startTime;

          return {
            id: 'perf-003',
            name: 'Database Function Performance',
            suite: 'Performance & Scalability',
            status: warnings.length === 0 ? 'pass' : 'fail',
            duration: totalDuration,
            timestamp: new Date().toISOString(),
            error: warnings.length > 0 ? warnings.join('; ') : undefined,
            details: {
              isModerator: isMod,
              isBanned,
              modDuration,
              banDuration,
              threshold,
              allFast: warnings.length === 0
            }
          };

        } catch (error) {
          return {
            id: 'perf-003',
            name: 'Database Function Performance',
            suite: 'Performance & Scalability',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        }
      }
    }
  ]
};
