import { supabase } from '@/lib/supabaseClient';
import type { ParkSubmissionData, RideSubmissionData, CompanySubmissionData, RideModelSubmissionData } from '@/types/submission-data';
import { handleNonCriticalError } from './errorHandler';
import {
  randomInt,
  randomFloat,
  randomItem,
  randomDate,
  randomDatePrecision,
  shouldPopulateField,
  generateWaterRideFields,
  generateDarkRideFields,
  generateFlatRideFields,
  generateKiddieRideFields,
  generateTransportationRideFields,
  generateRideMaterials,
  generateSourceUrl,
  generateSubmissionNotes,
  type FieldDensity
} from './testDataGeneratorHelpers';

// Preset configurations
export const PRESETS = {
  small: { parks: 5, rides: 10, companies: 3, rideModels: 2, photos: 5 },
  medium: { parks: 20, rides: 50, companies: 20, rideModels: 10, photos: 25 },
  large: { parks: 100, rides: 250, companies: 100, rideModels: 50, photos: 100 },
  stress: { parks: 400, rides: 1000, companies: 400, rideModels: 200, photos: 500 }
} as const;

// Word lists for realistic names
const PARK_ADJECTIVES = ['Adventure', 'Fantasy', 'Wonder', 'Magic', 'Dream', 'Thrill', 'Fun', 'Happy', 'Paradise', 'Epic'];
const PARK_NOUNS = ['World', 'Land', 'Park', 'Gardens', 'Kingdom', 'Realm', 'Island', 'Bay', 'Point', 'Valley'];
const RIDE_PREFIXES = ['Super', 'Mega', 'Ultra', 'Extreme', 'Wild', 'Crazy', 'Thunder', 'Lightning', 'Dragon', 'Phoenix'];
const RIDE_TYPES = ['Coaster', 'Drop', 'Spinner', 'Flyer', 'Racer', 'Twister', 'Loop', 'Screamer', 'Rush', 'Blast'];
const COMPANY_PREFIXES = ['Ace', 'Premier', 'Advanced', 'Dynamic', 'Innovative', 'Global', 'United', 'International'];
const COMPANY_SUFFIXES = ['Industries', 'Manufacturing', 'Enterprises', 'Solutions', 'Systems', 'Designs', 'Works', 'Creations'];

const CITIES = ['New York', 'Los Angeles', 'Chicago', 'London', 'Paris', 'Tokyo', 'Sydney', 'Toronto', 'Berlin', 'Madrid'];
const COUNTRIES = ['USA', 'UK', 'France', 'Japan', 'Australia', 'Canada', 'Germany', 'Spain', 'Italy', 'Netherlands'];

function generateSlug(name: string, counter?: number): string {
  let slug = name
    .toLowerCase()
    .replace(/[^a-z0-9\s-]/g, '')
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-')
    .replace(/^-+|-+$/g, '');
  
  if (counter) {
    slug += `-${counter}`;
  }
  
  return slug;
}

// Test data context for tracking created entities
export class TestDataContext {
  createdParks: Array<{ id: string; name: string }> = [];
  createdCompanies: Array<{ id: string; name: string; type: string }> = [];
  createdRideModels: Array<{ id: string; name: string; manufacturer_id: string }> = [];
  stats = {
    parks: 0,
    rides: 0,
    companies: 0,
    rideModels: 0,
    photos: 0,
    conflicts: 0,
    versionChains: 0
  };

  addPark(id: string, name: string) {
    this.createdParks.push({ id, name });
    this.stats.parks++;
  }

  addCompany(id: string, name: string, type: string) {
    this.createdCompanies.push({ id, name, type });
    this.stats.companies++;
  }

  addRideModel(id: string, name: string, manufacturer_id: string) {
    this.createdRideModels.push({ id, name, manufacturer_id });
    this.stats.rideModels++;
  }

  getRandomPark() {
    return this.createdParks.length > 0 ? randomItem(this.createdParks) : null;
  }

  getRandomCompany(type?: string) {
    const filtered = type 
      ? this.createdCompanies.filter(c => c.type === type)
      : this.createdCompanies;
    return filtered.length > 0 ? randomItem(filtered) : null;
  }

  getRandomRideModel() {
    return this.createdRideModels.length > 0 ? randomItem(this.createdRideModels) : null;
  }

  getSummary() {
    return this.stats;
  }
}

// Random data generators
export function generateRandomPark(counter: number, density: FieldDensity = 'mixed'): ParkSubmissionData {
  const name = `${randomItem(PARK_ADJECTIVES)} ${randomItem(PARK_NOUNS)}`;
  const slug = generateSlug(name, counter);
  const openingDate = randomDate(1950, 2024);
  const status = randomItem(['operating', 'operating', 'operating', 'seasonal']); // More likely to be operating
  
  const parkData: ParkSubmissionData = {
    name,
    slug,
    description: `A thrilling amusement park featuring world-class attractions and entertainment.`,
    park_type: randomItem(['theme_park', 'amusement_park', 'water_park', 'adventure_park']),
    status,
    opening_date: openingDate,
    opening_date_precision: randomDatePrecision(),
    website_url: `https://${slug}.example.com`,
    phone: `+1-555-${randomInt(100, 999)}-${randomInt(1000, 9999)}`,
    email: `info@${slug}.example.com`,
    operator_id: null,
    property_owner_id: null,
    location_id: null,
    banner_image_url: null,
    banner_image_id: null,
    card_image_url: null,
    card_image_id: null,
    is_test_data: true
  };

  // Add closing date for closed/seasonal parks
  if ((status === 'closed' || status === 'seasonal') && shouldPopulateField(density, counter, 'high')) {
    const openYear = parseInt(openingDate.split('-')[0]);
    parkData.closing_date = randomDate(openYear + 5, 2024);
    parkData.closing_date_precision = randomDatePrecision();
  }

  // Add source URL
  if (shouldPopulateField(density, counter, 'low')) {
    parkData.source_url = generateSourceUrl('park', counter);
  }

  // Add submission notes
  const notes = generateSubmissionNotes(density, counter, 'park');
  if (notes) {
    parkData.submission_notes = notes;
  }

  return parkData;
}

export function generateRandomRide(parkId: string, counter: number, density: FieldDensity = 'mixed'): RideSubmissionData {
  const name = `${randomItem(RIDE_PREFIXES)} ${randomItem(RIDE_TYPES)}`;
  const slug = generateSlug(name, counter);
  const category = randomItem(['roller_coaster', 'flat_ride', 'water_ride', 'dark_ride', 'family_ride', 'transport_ride', 'kiddie_ride']);
  const openingDate = randomDate(1980, 2024);
  const status = randomItem(['operating', 'operating', 'operating', 'seasonal']);
  
  const rideData: RideSubmissionData = {
    name,
    slug,
    description: `An exciting ${category.replace('_', ' ')} experience for all ages.`,
    category,
    ride_sub_type: null,
    status,
    park_id: parkId,
    ride_model_id: null,
    manufacturer_id: null,
    designer_id: null,
    opening_date: openingDate,
    opening_date_precision: randomDatePrecision(),
    closing_date: Math.random() > 0.95 ? randomDate(2010, 2024) : null,
    height_requirement: randomInt(90, 140),
    age_requirement: null,
    capacity_per_hour: randomInt(500, 2000),
    duration_seconds: randomInt(60, 300),
    max_speed_kmh: category === 'roller_coaster' ? randomFloat(40, 150, 1) : randomFloat(10, 60, 1),
    max_height_meters: category === 'roller_coaster' ? randomFloat(20, 100, 1) : randomFloat(5, 30, 1),
    length_meters: category === 'roller_coaster' ? randomFloat(500, 2500, 1) : null,
    drop_height_meters: category === 'roller_coaster' ? randomFloat(15, 80, 1) : null,
    inversions: category === 'roller_coaster' && Math.random() > 0.5 ? randomInt(1, 7) : 0,
    max_g_force: category === 'roller_coaster' ? randomFloat(2, 5, 1) : null,
    coaster_type: category === 'roller_coaster' ? randomItem(['steel', 'wooden', 'hybrid']) : null,
    seating_type: category === 'roller_coaster' ? randomItem(['sit_down', 'inverted', 'floorless', 'suspended']) : null,
    intensity_level: randomItem(['family', 'moderate', 'thrill', 'extreme']),
    banner_image_url: null,
    banner_image_id: null,
    card_image_url: null,
    card_image_id: null,
    image_url: null,
    is_test_data: true
  };

  // Add closing date precision if closing date exists
  if (rideData.closing_date && shouldPopulateField(density, counter, 'medium')) {
    rideData.closing_date_precision = randomDatePrecision();
  }

  // Add material arrays for appropriate rides
  if (category === 'roller_coaster' && shouldPopulateField(density, counter, 'medium')) {
    const materials = generateRideMaterials(category);
    Object.assign(rideData, materials);
  }

  // Add category-specific fields
  if (category === 'water_ride') {
    Object.assign(rideData, generateWaterRideFields(density, counter));
  } else if (category === 'dark_ride') {
    Object.assign(rideData, generateDarkRideFields(density, counter));
  } else if (category === 'flat_ride') {
    Object.assign(rideData, generateFlatRideFields(density, counter));
  } else if (category === 'kiddie_ride') {
    Object.assign(rideData, generateKiddieRideFields(density, counter));
  } else if (category === 'transport_ride') {
    Object.assign(rideData, generateTransportationRideFields(density, counter));
  }

  // Add source URL
  if (shouldPopulateField(density, counter, 'low')) {
    rideData.source_url = generateSourceUrl('ride', counter);
  }

  // Add submission notes
  const notes = generateSubmissionNotes(density, counter, 'ride');
  if (notes) {
    rideData.submission_notes = notes;
  }

  return rideData;
}

export function generateRandomCompany(type: 'manufacturer' | 'operator' | 'designer' | 'property_owner', counter: number, density: FieldDensity = 'mixed'): CompanySubmissionData {
  const name = `${randomItem(COMPANY_PREFIXES)} ${randomItem(COMPANY_SUFFIXES)}`;
  const slug = generateSlug(name, counter);
  const foundedYear = randomInt(1950, 2020);
  
  const companyData: CompanySubmissionData = {
    name,
    slug,
    company_type: type,
    description: `A leading ${type.replace('_', ' ')} in the amusement industry.`,
    person_type: Math.random() > 0.9 ? 'individual' : 'company',
    founded_year: foundedYear,
    headquarters_location: `${randomItem(CITIES)}, ${randomItem(COUNTRIES)}`,
    website_url: `https://${slug}.example.com`,
    logo_url: null,
    banner_image_url: null,
    banner_image_id: null,
    card_image_url: null,
    card_image_id: null,
    is_test_data: true
  };

  // Add full founded date with precision
  if (shouldPopulateField(density, counter, 'medium')) {
    companyData.founded_date = `${foundedYear}-01-01`;
    companyData.founded_date_precision = randomItem(['year', 'month', 'exact']);
  }

  // Add defunct date for some companies
  if (shouldPopulateField(density, counter, 'low') && Math.random() > 0.85) {
    const defunctYear = randomInt(foundedYear + 10, 2024);
    companyData.defunct_date = `${defunctYear}-12-31`;
    companyData.defunct_date_precision = randomItem(['year', 'month', 'exact']);
  }

  // Add source URL
  if (shouldPopulateField(density, counter, 'low')) {
    companyData.source_url = generateSourceUrl('company', counter);
  }

  // Add submission notes
  const notes = generateSubmissionNotes(density, counter, 'company');
  if (notes) {
    companyData.submission_notes = notes;
  }

  return companyData;
}

export function generateRandomRideModel(manufacturerId: string, counter: number, density: FieldDensity = 'mixed'): RideModelSubmissionData {
  const name = `${randomItem(RIDE_PREFIXES)} Model ${randomInt(100, 999)}`;
  const slug = generateSlug(name, counter);
  const category = randomItem(['roller_coaster', 'flat_ride', 'water_ride', 'dark_ride']);
  
  const modelData: RideModelSubmissionData = {
    name,
    slug,
    manufacturer_id: manufacturerId,
    category,
    ride_type: randomItem(['spinning', 'launch', 'inverted', 'suspended', 'floorless']),
    description: `A state-of-the-art ${category.replace('_', ' ')} model.`,
    banner_image_url: null,
    banner_image_id: null,
    card_image_url: null,
    card_image_id: null,
    is_test_data: true
  };

  // Add source URL
  if (shouldPopulateField(density, counter, 'low')) {
    modelData.source_url = generateSourceUrl('ride-model', counter);
  }

  // Add submission notes
  const notes = generateSubmissionNotes(density, counter, 'ride model');
  if (notes) {
    modelData.submission_notes = notes;
  }

  return modelData;
}

// Cleanup utilities
export async function clearTestData(): Promise<{ deleted: number }> {
  try {
    // Find all test submissions by querying submission_metadata
    const { data: testMetadata, error: metadataError } = await supabase
      .from('submission_metadata')
      .select('submission_id')
      .eq('metadata_key', 'is_test_data')
      .eq('metadata_value', 'true');

    if (metadataError) throw metadataError;
    
    const submissionIds = testMetadata?.map(m => m.submission_id) || [];
    const submissionCount = submissionIds.length;

    // Delete submissions if found
    if (submissionCount > 0) {
      const batchSize = 100;

      for (let i = 0; i < submissionIds.length; i += batchSize) {
        const batch = submissionIds.slice(i, i + batchSize);

        const { error: deleteError } = await supabase
          .from('content_submissions')
          .delete()
          .in('id', batch);

        if (deleteError) throw deleteError;
      }
    }

    // Clear the test data registry
    const { error: registryError } = await supabase
      .from('test_data_registry')
      .delete()
      .neq('id', '00000000-0000-0000-0000-000000000000'); // Delete all records
    
    if (registryError) {
      handleNonCriticalError(registryError, {
        action: 'Clear test data registry',
        metadata: { operation: 'clearTestData' }
      });
    }

    return { deleted: submissionCount };
  } catch (error: unknown) {
    handleNonCriticalError(error, {
      action: 'Clear test data',
      metadata: { operation: 'clearTestData' }
    });
    throw error;
  }
}

export async function getTestDataStats(): Promise<{ 
  total: number; 
  pending: number; 
  approved: number;
  operators: number;
  property_owners: number;
  manufacturers: number;
  designers: number;
  parks: number;
  rides: number;
  ride_models: number;
}> {
  // Query submission_metadata to find test submissions
  const { data: testMetadata, error: metadataError } = await supabase
    .from('submission_metadata')
    .select('submission_id')
    .eq('metadata_key', 'is_test_data')
    .eq('metadata_value', 'true');

  if (metadataError) throw metadataError;

  const submissionIds = testMetadata?.map(m => m.submission_id) || [];

  // Get statuses for test submissions
  let data: Array<{ status: string }> = [];
  if (submissionIds.length > 0) {
    const { data: submissions, error } = await supabase
      .from('content_submissions')
      .select('status')
      .in('id', submissionIds);

    if (error) throw error;
    data = submissions || [];
  }

  // Get registry counts for available dependencies
  const { data: registryData } = await supabase
    .from('test_data_registry')
    .select('entity_type');

  const registryCounts = registryData?.reduce((acc, row) => {
    acc[row.entity_type] = (acc[row.entity_type] || 0) + 1;
    return acc;
  }, {} as Record<string, number>) || {};

  const stats = {
    total: data.length,
    pending: data.filter(s => s.status === 'pending').length,
    approved: data.filter(s => s.status === 'approved').length,
    operators: registryCounts['operator'] || 0,
    property_owners: registryCounts['property_owner'] || 0,
    manufacturers: registryCounts['manufacturer'] || 0,
    designers: registryCounts['designer'] || 0,
    parks: registryCounts['park'] || 0,
    rides: registryCounts['ride'] || 0,
    ride_models: registryCounts['ride_model'] || 0
  };

  return stats;
}
