/**
 * Submission Pipeline Validation Tests
 * 
 * Tests submission creation, validation, and the full approval flow.
 * All tests follow the sacred pipeline architecture.
 */

import { supabase } from '@/lib/supabaseClient';
import type { TestSuite, TestResult } from '../testRunner';
import { TestDataTracker } from '../TestDataTracker';
import { formatTestError } from '../formatTestError';
import {
  generateUniqueParkData,
  generateUniqueRideData,
  generateUniqueCompanyData,
  generateUniqueRideModelData,
  createTestParkSubmission,
  createTestRideSubmission,
  createTestCompanySubmission,
  createTestRideModelSubmission,
  approveSubmission,
  pollForEntity,
  getAuthToken,
  getCurrentUserId,
} from '../helpers/approvalTestHelpers';

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

        try {
          const userId = await getCurrentUserId();
          const authToken = await getAuthToken();
          const parkData = generateUniqueParkData('submission-001');

          // Create submission
          const { submissionId, itemId } = await createTestParkSubmission(parkData, userId, tracker);

          // Verify submission was created
          const { data: submission } = await supabase
            .from('content_submissions')
            .select('status, submission_type')
            .eq('id', submissionId)
            .single();

          if (!submission) throw new Error('Submission not found');
          if (submission.status !== 'pending') {
            throw new Error(`Expected status "pending", got "${submission.status}"`);
          }
          if (submission.submission_type !== 'park') {
            throw new Error(`Expected type "park", got "${submission.submission_type}"`);
          }

          // Approve submission
          const approval = await approveSubmission(submissionId, [itemId], authToken);
          if (!approval.success) {
            throw new Error(`Approval failed: ${approval.error}`);
          }

          // Verify entity was created
          const { data: item } = await supabase
            .from('submission_items')
            .select('approved_entity_id, status')
            .eq('id', itemId)
            .single();

          if (!item?.approved_entity_id) {
            throw new Error('No entity created after approval');
          }
          if (item.status !== 'approved') {
            throw new Error(`Expected item status "approved", got "${item.status}"`);
          }

          tracker.track('parks', item.approved_entity_id);

          // Verify park data
          const park = await pollForEntity('parks', item.approved_entity_id);
          if (!park) throw new Error('Park entity not found');
          
          if (park.name !== parkData.name) {
            throw new Error(`Expected name "${parkData.name}", got "${park.name}"`);
          }
          if (park.slug !== parkData.slug) {
            throw new Error(`Expected slug "${parkData.slug}", got "${park.slug}"`);
          }

          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: {
              submissionId,
              parkId: item.approved_entity_id,
              validationsPassed: ['submission_created', 'approval_succeeded', 'entity_created']
            }
          };

        } catch (error) {
          return {
            id: 'submission-001',
            name: 'Park Creation Validation',
            suite: 'Entity Submission & Validation',
            status: 'fail',
            duration: Date.now() - startTime,
            error: formatTestError(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          await tracker.cleanup();
        }
      }
    },
    {
      id: 'submission-002',
      name: 'Ride Creation with Dependencies',
      description: 'Validates ride submission requires valid park and creates correctly',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();

        try {
          const userId = await getCurrentUserId();
          const authToken = await getAuthToken();
          
          // First create and approve a park
          const parkData = generateUniqueParkData('submission-002-park');
          const { submissionId: parkSubId, itemId: parkItemId } = await createTestParkSubmission(parkData, userId, tracker);
          
          const parkApproval = await approveSubmission(parkSubId, [parkItemId], authToken);
          if (!parkApproval.success) {
            throw new Error(`Park approval failed: ${parkApproval.error}`);
          }

          const { data: parkItem } = await supabase
            .from('submission_items')
            .select('approved_entity_id')
            .eq('id', parkItemId)
            .single();

          const parkId = parkItem?.approved_entity_id;
          if (!parkId) throw new Error('Park not created');
          
          tracker.track('parks', parkId);

          // Now create ride submission
          const rideData = generateUniqueRideData(parkId, 'submission-002');
          const { submissionId: rideSubId, itemId: rideItemId } = await createTestRideSubmission(rideData, userId, tracker);

          // Approve ride
          const rideApproval = await approveSubmission(rideSubId, [rideItemId], authToken);
          if (!rideApproval.success) {
            throw new Error(`Ride approval failed: ${rideApproval.error}`);
          }

          // Verify ride created
          const { data: rideItem } = await supabase
            .from('submission_items')
            .select('approved_entity_id')
            .eq('id', rideItemId)
            .single();

          const rideId = rideItem?.approved_entity_id;
          if (!rideId) throw new Error('Ride not created after approval');

          tracker.track('rides', rideId);

          // Verify ride data
          const ride = await pollForEntity('rides', rideId);
          if (!ride) throw new Error('Ride entity not found');
          
          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: ['park_created', 'ride_created', 'dependency_valid']
            }
          };

        } catch (error) {
          return {
            id: 'submission-002',
            name: 'Ride Creation with Dependencies',
            suite: 'Entity Submission & Validation',
            status: 'fail',
            duration: Date.now() - startTime,
            error: formatTestError(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          await tracker.cleanup();
        }
      }
    },
    {
      id: 'submission-003',
      name: 'Company Creation All Types',
      description: 'Validates company submission for all company types',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();

        try {
          const userId = await getCurrentUserId();
          const authToken = await getAuthToken();
          const companyTypes = ['manufacturer', 'operator', 'designer', 'property_owner'] as const;
          const createdCompanies: Array<{ type: string; id: string }> = [];
          
          for (const companyType of companyTypes) {
            const companyData = generateUniqueCompanyData(companyType, `submission-003-${companyType}`);
            
            // Create submission
            const { submissionId, itemId } = await createTestCompanySubmission(
              companyType,
              companyData,
              userId,
              tracker
            );

            // Approve submission
            const approval = await approveSubmission(submissionId, [itemId], authToken);
            if (!approval.success) {
              throw new Error(`${companyType} approval failed: ${approval.error}`);
            }

            // Verify entity created
            const { data: item } = await supabase
              .from('submission_items')
              .select('approved_entity_id')
              .eq('id', itemId)
              .single();

            const companyId = item?.approved_entity_id;
            if (!companyId) {
              throw new Error(`${companyType} not created after approval`);
            }

            tracker.track('companies', companyId);

            // Verify company type
            const company = await pollForEntity('companies', companyId);
            if (!company) throw new Error(`${companyType} entity not found`);
            
            if (company.company_type !== companyType) {
              throw new Error(`Expected company_type "${companyType}", got "${company.company_type}"`);
            }

            createdCompanies.push({ type: companyType, id: companyId });
          }

          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: createdCompanies.length,
              companyTypes: companyTypes,
              companies: createdCompanies
            }
          };

        } catch (error) {
          return {
            id: 'submission-003',
            name: 'Company Creation All Types',
            suite: 'Entity Submission & Validation',
            status: 'fail',
            duration: Date.now() - startTime,
            error: formatTestError(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          await tracker.cleanup();
        }
      }
    },
    {
      id: 'submission-004',
      name: 'Ride Model with Images',
      description: 'Validates ride model submission with image fields',
      run: async (): Promise<TestResult> => {
        const startTime = Date.now();
        const tracker = new TestDataTracker();

        try {
          const userId = await getCurrentUserId();
          const authToken = await getAuthToken();
          
          // Create and approve manufacturer
          const mfgData = generateUniqueCompanyData('manufacturer', 'submission-004-mfg');
          const { submissionId: mfgSubId, itemId: mfgItemId } = await createTestCompanySubmission(
            'manufacturer',
            mfgData,
            userId,
            tracker
          );

          const mfgApproval = await approveSubmission(mfgSubId, [mfgItemId], authToken);
          if (!mfgApproval.success) {
            throw new Error(`Manufacturer approval failed: ${mfgApproval.error}`);
          }

          const { data: mfgItem } = await supabase
            .from('submission_items')
            .select('approved_entity_id')
            .eq('id', mfgItemId)
            .single();

          const manufacturerId = mfgItem?.approved_entity_id;
          if (!manufacturerId) throw new Error('Manufacturer not created');
          
          tracker.track('companies', manufacturerId);

          // Create ride model submission
          const modelData = generateUniqueRideModelData(manufacturerId, 'submission-004');
          const { submissionId, itemId } = await createTestRideModelSubmission(modelData, userId, tracker);

          // Approve ride model
          const approval = await approveSubmission(submissionId, [itemId], authToken);
          if (!approval.success) {
            throw new Error(`Ride model approval failed: ${approval.error}`);
          }

          // Verify entity created
          const { data: item } = await supabase
            .from('submission_items')
            .select('approved_entity_id')
            .eq('id', itemId)
            .single();

          const modelId = item?.approved_entity_id;
          if (!modelId) throw new Error('Ride model not created after approval');

          tracker.track('ride_models', modelId);

          // Verify model data
          const model = await pollForEntity('ride_models', modelId);
          if (!model) throw new Error('Ride model entity not found');
          
          if (model.manufacturer_id !== manufacturerId) {
            throw new Error(`Expected manufacturer_id "${manufacturerId}", got "${model.manufacturer_id}"`);
          }

          // Verify version created
          const { data: version } = await supabase
            .from('ride_model_versions')
            .select('version_number')
            .eq('ride_model_id', modelId)
            .eq('version_number', 1)
            .single();

          if (!version) throw new Error('Version not created for ride model');

          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,
              versionCreated: true,
              followedPipeline: true
            }
          };

        } catch (error) {
          return {
            id: 'submission-004',
            name: 'Ride Model with Images',
            suite: 'Entity Submission & Validation',
            status: 'fail',
            duration: Date.now() - startTime,
            error: formatTestError(error),
            timestamp: new Date().toISOString()
          };
        } finally {
          await tracker.cleanup();
        }
      }
    }
  ]
};
