/**
 * Entity Submission & Validation Integration Tests
 * 
 * Tests for submission validation, schema validation, and entity creation.
 */

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

export const submissionTestSuite: TestSuite = {
  id: 'submission',
  name: 'Entity Submission & Validation',
  description: 'Tests for entity submission workflows and validation schemas',
  tests: [
    {
      id: 'submission-001',
      name: 'Park Creation Validation',
      description: 'Validates park submission and creation',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();
        let parkId: string | null = null;

        try {
          const parkSlug = `test-park-submit-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;

          // Create park with valid data
          const { data: park, error: createError } = await supabase
            .from('parks')
            .insert({
              name: 'Test Park Submission',
              slug: parkSlug,
              park_type: 'theme_park',
              status: 'operating',
              description: 'Test park for submission validation'
            })
            .select('id, name, slug, park_type, status')
            .single();

          if (createError) throw new Error(`Park creation failed: ${createError.message}`);
          if (!park) throw new Error('Park not returned after creation');

          parkId = park.id;

          // Validate created park has correct data
          if (park.name !== 'Test Park Submission') {
            throw new Error(`Expected name "Test Park Submission", got "${park.name}"`);
          }
          if (park.slug !== parkSlug) {
            throw new Error(`Expected slug "${parkSlug}", got "${park.slug}"`);
          }
          if (park.park_type !== 'theme_park') {
            throw new Error(`Expected park_type "theme_park", got "${park.park_type}"`);
          }

          // Test slug uniqueness constraint
          const { error: duplicateError } = await supabase
            .from('parks')
            .insert({
              name: 'Duplicate Slug Park',
              slug: parkSlug, // Same slug
              park_type: 'theme_park',
              status: 'operating'
            });

          if (!duplicateError) {
            throw new Error('Duplicate slug was allowed (uniqueness constraint failed)');
          }

          const duration = Date.now() - startTime;

          return {
            id: 'submission-001',
            name: 'Park Creation Validation',
            suite: 'Entity Submission & Validation',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              parkId,
              parkSlug,
              validationsPassed: ['name', 'slug', 'park_type', 'uniqueness_constraint']
            }
          };

        } catch (error) {
          return {
            id: 'submission-001',
            name: 'Park Creation Validation',
            suite: 'Entity Submission & Validation',
            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('submission-001 cleanup incomplete:', remaining);
          }
        }
      }
    },
    {
      id: 'submission-002',
      name: 'Ride Creation with Dependencies',
      description: 'Validates ride submission requires valid park_id',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();
        let parkId: string | null = null;
        let rideId: string | null = null;

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

          if (parkError) throw new Error(`Park creation failed: ${parkError.message}`);
          parkId = park.id;

          // Try to create ride with invalid park_id (should fail)
          const invalidParkId = '00000000-0000-0000-0000-000000000000';
          const { error: invalidError } = await supabase
            .from('rides')
            .insert({
              name: 'Test Ride Invalid Park',
              slug: `test-ride-invalid-${Date.now()}`,
              park_id: invalidParkId,
              category: 'roller_coaster',
              status: 'operating'
            });

          if (!invalidError) {
            throw new Error('Ride with invalid park_id was allowed (foreign key constraint failed)');
          }

          // Create ride with valid park_id (should succeed)
          const rideSlug = `test-ride-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
          const { data: ride, error: rideError } = await supabase
            .from('rides')
            .insert({
              name: 'Test Ride Valid Park',
              slug: rideSlug,
              park_id: parkId,
              category: 'roller_coaster',
              status: 'operating'
            })
            .select('id, name, park_id')
            .single();

          if (rideError) throw new Error(`Ride creation failed: ${rideError.message}`);
          if (!ride) throw new Error('Ride not returned after creation');

          rideId = ride.id;

          if (ride.park_id !== parkId) {
            throw new Error(`Expected park_id "${parkId}", got "${ride.park_id}"`);
          }

          const duration = Date.now() - startTime;

          return {
            id: 'submission-002',
            name: 'Ride Creation with Dependencies',
            suite: 'Entity Submission & Validation',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              parkId,
              rideId,
              validationsPassed: ['foreign_key_constraint', 'valid_dependency']
            }
          };

        } catch (error) {
          return {
            id: 'submission-002',
            name: 'Ride Creation with Dependencies',
            suite: 'Entity Submission & Validation',
            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('submission-002 cleanup incomplete:', remaining);
          }
        }
      }
    },
    {
      id: 'submission-003',
      name: 'Company Creation All Types',
      description: 'Validates company creation for all company types',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();
        const companyIds: string[] = [];

        try {
          const companyTypes = ['manufacturer', 'operator', 'designer', 'property_owner'] as const;
          
          for (const companyType of companyTypes) {
            const slug = `test-company-${companyType}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
            
            const { data: company, error: createError } = await supabase
              .from('companies')
              .insert({
                name: `Test ${companyType} Company`,
                slug,
                company_type: companyType,
                description: `Test company of type ${companyType}`
              })
              .select('id, company_type')
              .single();

            if (createError) {
              throw new Error(`${companyType} creation failed: ${createError.message}`);
            }
            if (!company) {
              throw new Error(`${companyType} not returned after creation`);
            }

            companyIds.push(company.id);
            tracker.track('companies', company.id);

            if (company.company_type !== companyType) {
              throw new Error(`Expected company_type "${companyType}", got "${company.company_type}"`);
            }
          }

          const duration = Date.now() - startTime;

          return {
            id: 'submission-003',
            name: 'Company Creation All Types',
            suite: 'Entity Submission & Validation',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              companiesCreated: companyIds.length,
              companyTypes: companyTypes,
              companyIds
            }
          };

        } catch (error) {
          return {
            id: 'submission-003',
            name: 'Company Creation All Types',
            suite: 'Entity Submission & Validation',
            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('submission-003 cleanup incomplete:', remaining);
          }
        }
      }
    },
    {
      id: 'submission-004',
      name: 'Ride Model with Images',
      description: 'Validates ride model creation with image fields',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        let manufacturerId: string | null = null;
        let modelId: string | null = null;

        try {
          // Create manufacturer first
          const mfgSlug = `test-mfg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
          const { data: manufacturer, error: mfgError } = await supabase
            .from('companies')
            .insert({
              name: 'Test Manufacturer',
              slug: mfgSlug,
              company_type: 'manufacturer'
            })
            .select('id')
            .single();

          if (mfgError) throw new Error(`Manufacturer creation failed: ${mfgError.message}`);
          manufacturerId = manufacturer.id;

          // Create ride model with images
          const modelSlug = `test-model-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
          const testImageUrl = 'https://imagedelivery.net/test-account/test-image-id/public';
          const testImageId = 'test-image-id';

          const { data: model, error: modelError } = await supabase
            .from('ride_models')
            .insert({
              name: 'Test Ride Model',
              slug: modelSlug,
              manufacturer_id: manufacturerId,
              category: 'roller_coaster',
              ride_type: 'steel_coaster',
              banner_image_url: testImageUrl,
              banner_image_id: testImageId,
              card_image_url: testImageUrl,
              card_image_id: testImageId
            })
            .select('id, banner_image_url, banner_image_id, card_image_url, card_image_id')
            .single();

          if (modelError) throw new Error(`Ride model creation failed: ${modelError.message}`);
          if (!model) throw new Error('Ride model not returned after creation');

          modelId = model.id;

          // Validate image fields
          if (model.banner_image_url !== testImageUrl) {
            throw new Error(`banner_image_url mismatch: expected "${testImageUrl}", got "${model.banner_image_url}"`);
          }
          if (model.banner_image_id !== testImageId) {
            throw new Error(`banner_image_id mismatch: expected "${testImageId}", got "${model.banner_image_id}"`);
          }
          if (model.card_image_url !== testImageUrl) {
            throw new Error(`card_image_url mismatch`);
          }
          if (model.card_image_id !== testImageId) {
            throw new Error(`card_image_id mismatch`);
          }

          // Verify version was created with images
          let version: any = null;
          const pollStart = Date.now();
          while (!version && Date.now() - pollStart < 5000) {
            const { data } = await supabase
              .from('ride_model_versions')
              .select('banner_image_url, banner_image_id, card_image_url, card_image_id')
              .eq('ride_model_id', modelId)
              .eq('version_number', 1)
              .single();
            
            if (data) {
              version = data;
              break;
            }
            await new Promise(resolve => setTimeout(resolve, 100));
          }

          if (!version) throw new Error('Version not created after 5s timeout');
          if (version.banner_image_url !== testImageUrl) {
            throw new Error('Version missing banner_image_url');
          }

          const duration = Date.now() - startTime;

          return {
            id: 'submission-004',
            name: 'Ride Model with Images',
            suite: 'Entity Submission & Validation',
            status: 'pass',
            duration,
            timestamp: new Date().toISOString(),
            details: {
              modelId,
              manufacturerId,
              imageFieldsValidated: ['banner_image_url', 'banner_image_id', 'card_image_url', 'card_image_id'],
              versionCreated: true
            }
          };

        } catch (error) {
          return {
            id: 'submission-004',
            name: 'Ride Model with Images',
            suite: 'Entity Submission & Validation',
            status: 'fail',
            duration: Date.now() - startTime,
            error: error instanceof Error ? error.message : String(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          if (modelId) {
            await supabase.from('ride_models').delete().eq('id', modelId);
          }
          if (manufacturerId) {
            await supabase.from('companies').delete().eq('id', manufacturerId);
          }
        }
      }
    }
  ]
};
