import { useState, useEffect } from 'react';
import { invokeWithTracking } from '@/lib/edgeFunctionTracking';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Progress } from '@/components/ui/progress';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler';
import { Beaker, CheckCircle, ChevronDown, Trash2, AlertTriangle } from 'lucide-react';
import { clearTestData, getTestDataStats } from '@/lib/testDataGenerator';
import { TestDataTracker } from '@/lib/integrationTests/TestDataTracker';
import { logger } from '@/lib/logger';

const PRESETS = {
  small: { label: 'Small', description: '~30 submissions - Quick test', counts: '5 parks, 10 rides, 3 companies, 2 models, 5 photo sets' },
  medium: { label: 'Medium', description: '~125 submissions - Standard testing', counts: '20 parks, 50 rides, 20 companies, 10 models, 25 photo sets' },
  large: { label: 'Large', description: '~600 submissions - Performance testing', counts: '100 parks, 250 rides, 100 companies, 50 models, 100 photo sets' },
  stress: { label: 'Stress', description: '~2600 submissions - Load testing', counts: '400 parks, 1000 rides, 400 companies, 200 models, 500 photo sets' }
};

interface TestDataResults {
  summary: {
    operators: number;
    property_owners: number;
    manufacturers: number;
    designers: number;
    parks: number;
    rides: number;
    rideModels: number;
    photos: number;
    totalPhotoItems: number;
    conflicts: number;
    versionChains: number;
    companies?: number;
  };
  time?: string;
}

export function TestDataGenerator(): React.JSX.Element {
  const { toast } = useToast();
  const [preset, setPreset] = useState<'small' | 'medium' | 'large' | 'stress'>('small');
  const [fieldDensity, setFieldDensity] = useState<'mixed' | 'minimal' | 'standard' | 'maximum'>('mixed');
  const [entityTypes, setEntityTypes] = useState({
    parks: true,
    rides: true,
    manufacturers: true,
    operators: true,
    property_owners: true,
    designers: true,
    ride_models: true,
    photos: true
  });
  const [options, setOptions] = useState({
    includeDependencies: true,
    includeConflicts: false,
    includeVersionChains: false,
    includeEscalated: false,
    includeExpiredLocks: false
  });
  const [loading, setLoading] = useState(false);
  const [results, setResults] = useState<TestDataResults | null>(null);
  const [stats, setStats] = useState<{ 
    total: number; 
    pending: number; 
    approved: number;
    operators: number;
    property_owners: number;
    manufacturers: number;
    designers: number;
    parks: number;
    rides: number;
    ride_models: number;
  } | null>(null);

  const selectedEntityTypes = Object.entries(entityTypes)
    .filter(([, enabled]) => enabled)
    .map(([type]) => type);

  useEffect(() => {
    void loadStats();
  }, []);

  const loadStats = async (): Promise<void> => {
    try {
      const data = await getTestDataStats();
      setStats(data);
    } catch (error: unknown) {
      logger.error('Failed to load test data stats', { error: getErrorMessage(error) });
    }
  };

  const handleGenerate = async (): Promise<void> => {
    setLoading(true);
    setResults(null);

    try {
      const stages = ['companies', 'parks', 'rides', 'photos'] as const;
      const allResults = {
        operators: 0,
        property_owners: 0,
        manufacturers: 0,
        designers: 0,
        parks: 0,
        rides: 0,
        rideModels: 0,
        photos: 0,
        totalPhotoItems: 0,
        conflicts: 0,
        versionChains: 0
      };

      for (let i = 0; i < stages.length; i++) {
        const stage = stages[i];
        
        toast({
          title: `Stage ${i + 1}/${stages.length}`,
          description: `Generating ${stage}...`,
        });

        const { data, error } = await invokeWithTracking(
          'seed-test-data',
          {
            preset,
            fieldDensity,
            entityTypes: selectedEntityTypes,
            stage,
            ...options
          },
          (await supabase.auth.getUser()).data.user?.id
        );

        if (error) throw error;

        // Merge results
        const summary = data.summary as Record<string, number>;
        Object.keys(summary).forEach(key => {
          if (allResults[key as keyof typeof allResults] !== undefined) {
            allResults[key as keyof typeof allResults] += summary[key];
          }
        });
      }

      setResults({ summary: allResults });
      toast({
        title: "Test data generated",
        description: `Successfully completed all stages`,
      });
      
      await loadStats();
    } catch (error: unknown) {
      toast({
        title: "Generation failed",
        description: getErrorMessage(error),
        variant: "destructive",
      });
    } finally {
      setLoading(false);
    }
  };

  const handleClear = async (): Promise<void> => {
    setLoading(true);

    try {
      const { deleted } = await clearTestData();
      await loadStats();

      toast({
        title: 'Test Data Cleared',
        description: `Removed ${deleted} test submissions`
      });
      setResults(null);
    } catch (error: unknown) {
      toast({
        title: 'Clear Failed',
        description: getErrorMessage(error),
        variant: 'destructive'
      });
    } finally {
      setLoading(false);
    }
  };

  const handleEmergencyCleanup = async (): Promise<void> => {
    setLoading(true);

    try {
      const { deleted, errors } = await TestDataTracker.bulkCleanupAllTestData();
      await loadStats();

      toast({
        title: 'Emergency Cleanup Complete',
        description: `Deleted ${deleted} test records across all tables${errors > 0 ? `, ${errors} errors` : ''}`
      });
      setResults(null);
    } catch (error: unknown) {
      toast({
        title: 'Emergency Cleanup Failed',
        description: getErrorMessage(error),
        variant: 'destructive'
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center gap-2">
          <Beaker className="w-5 h-5" />
          <CardTitle>Test Data Generator</CardTitle>
        </div>
        <CardDescription>
          Generate comprehensive test submissions with varying field density and photo support
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        <Alert variant="destructive">
          <AlertTriangle className="h-4 w-4" />
          <AlertDescription>
            This will create test data in your database. All test submissions are marked and can be cleared later.
          </AlertDescription>
        </Alert>

        {stats && (
          <div className="space-y-2">
            <div className="flex gap-4 text-sm text-muted-foreground">
              <span>Total Test Data: {stats.total}</span>
              <span>Pending: {stats.pending}</span>
              <span>Approved: {stats.approved}</span>
            </div>
            
            {(stats.operators > 0 || stats.property_owners > 0 || stats.manufacturers > 0 || 
              stats.designers > 0 || stats.parks > 0 || stats.rides > 0 || stats.ride_models > 0) && (
              <Alert>
                <AlertDescription>
                  <div className="text-sm">
                    <p className="font-medium mb-2">Available Test Dependencies:</p>
                    <ul className="space-y-1">
                      {stats.operators > 0 && <li>• {stats.operators} test operator{stats.operators > 1 ? 's' : ''}</li>}
                      {stats.property_owners > 0 && <li>• {stats.property_owners} test property owner{stats.property_owners > 1 ? 's' : ''}</li>}
                      {stats.manufacturers > 0 && <li>• {stats.manufacturers} test manufacturer{stats.manufacturers > 1 ? 's' : ''}</li>}
                      {stats.designers > 0 && <li>• {stats.designers} test designer{stats.designers > 1 ? 's' : ''}</li>}
                      {stats.parks > 0 && <li>• {stats.parks} test park{stats.parks > 1 ? 's' : ''}</li>}
                      {stats.rides > 0 && <li>• {stats.rides} test ride{stats.rides > 1 ? 's' : ''}</li>}
                      {stats.ride_models > 0 && <li>• {stats.ride_models} test ride model{stats.ride_models > 1 ? 's' : ''}</li>}
                    </ul>
                    <p className="text-xs text-muted-foreground mt-2">
                      Enable "Include Dependencies" to link new entities to these existing test entities.
                    </p>
                  </div>
                </AlertDescription>
              </Alert>
            )}
            
            {/* Dependency warnings */}
            {entityTypes.rides && stats.parks === 0 && !entityTypes.parks && (
              <Alert variant="destructive">
                <AlertTriangle className="h-4 w-4" />
                <AlertDescription>
                  <strong>Missing Dependency:</strong> You've selected "rides" but no parks exist. 
                  Rides require parks to be created first. Either enable "parks" or generate parks separately first.
                </AlertDescription>
              </Alert>
            )}
            
            {entityTypes.ride_models && stats.manufacturers === 0 && !entityTypes.manufacturers && (
              <Alert variant="destructive">
                <AlertTriangle className="h-4 w-4" />
                <AlertDescription>
                  <strong>Missing Dependency:</strong> You've selected "ride models" but no manufacturers exist. 
                  Ride models require manufacturers to be created first. Either enable "manufacturers" or generate manufacturers separately first.
                </AlertDescription>
              </Alert>
            )}
            
            {(entityTypes.parks || entityTypes.rides) && 
             stats.operators === 0 && stats.property_owners === 0 && 
             !entityTypes.operators && !entityTypes.property_owners && (
              <Alert>
                <AlertTriangle className="h-4 w-4" />
                <AlertDescription>
                  <strong>Optional Dependencies:</strong> Parks and rides can optionally link to operators and property owners. 
                  Consider enabling "operators" and "property_owners" for more realistic test data with proper dependency chains.
                </AlertDescription>
              </Alert>
            )}
          </div>
        )}

        <div className="space-y-4">
          <div>
            <Label className="text-base font-semibold">Preset</Label>
            <RadioGroup value={preset} onValueChange={(v: string) => setPreset(v as 'small' | 'medium' | 'large' | 'stress')} className="mt-2 space-y-3">
              {Object.entries(PRESETS).map(([key, { label, description, counts }]) => (
                <div key={key} className="flex items-start space-x-2">
                  <RadioGroupItem value={key} id={key} className="mt-1" />
                  <div className="flex-1">
                    <Label htmlFor={key} className="font-medium cursor-pointer">{label}</Label>
                    <p className="text-sm text-muted-foreground">{description}</p>
                    <p className="text-xs text-muted-foreground">{counts}</p>
                  </div>
                </div>
              ))}
            </RadioGroup>
          </div>

          <div>
            <Label className="text-base font-semibold">Field Population Density</Label>
            <p className="text-sm text-muted-foreground mt-1 mb-3">
              Controls how many optional fields are populated in generated entities
            </p>
            <RadioGroup value={fieldDensity} onValueChange={(v: string) => setFieldDensity(v as 'mixed' | 'minimal' | 'standard' | 'maximum')} className="space-y-2">
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="mixed" id="mixed" />
                <Label htmlFor="mixed" className="cursor-pointer">
                  <span className="font-medium">Mixed</span> - Random levels (most realistic)
                </Label>
              </div>
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="minimal" id="minimal" />
                <Label htmlFor="minimal" className="cursor-pointer">
                  <span className="font-medium">Minimal</span> - Required fields only
                </Label>
              </div>
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="standard" id="standard" />
                <Label htmlFor="standard" className="cursor-pointer">
                  <span className="font-medium">Standard</span> - 50% optional fields
                </Label>
              </div>
              <div className="flex items-center space-x-2">
                <RadioGroupItem value="maximum" id="maximum" />
                <Label htmlFor="maximum" className="cursor-pointer">
                  <span className="font-medium">Maximum</span> - All fields + technical data
                </Label>
              </div>
            </RadioGroup>
          </div>

          <div>
            <Label className="text-base font-semibold">Entity Types</Label>
            <div className="mt-2 grid grid-cols-2 gap-3">
              {Object.entries(entityTypes).map(([key, enabled]) => (
                <div key={key} className="flex items-center space-x-2">
                  <Checkbox
                    id={key}
                    checked={enabled}
                    onCheckedChange={(checked) =>
                      setEntityTypes({ ...entityTypes, [key]: !!checked })
                    }
                  />
                  <Label htmlFor={key} className="cursor-pointer capitalize">
                    {key.replace('_', ' ')}
                  </Label>
                </div>
              ))}
            </div>
          </div>

          <Collapsible>
            <CollapsibleTrigger className="flex items-center gap-2 text-sm font-medium">
              <ChevronDown className="w-4 h-4" />
              Advanced Options
            </CollapsibleTrigger>
            <CollapsibleContent className="mt-3 space-y-3">
              {Object.entries(options).map(([key, enabled]) => (
                <div key={key} className="flex items-center space-x-2">
                  <Checkbox
                    id={key}
                    checked={enabled}
                    onCheckedChange={(checked) =>
                      setOptions({ ...options, [key]: !!checked })
                    }
                  />
                  <Label htmlFor={key} className="cursor-pointer capitalize">
                    {key.replace(/([A-Z])/g, ' $1').toLowerCase()}
                  </Label>
                </div>
              ))}
            </CollapsibleContent>
          </Collapsible>
        </div>

        {loading && (
          <div className="space-y-2">
            <Progress value={undefined} />
            <p className="text-sm text-center text-muted-foreground">Generating test data...</p>
          </div>
        )}

        {results && (
          <Alert>
            <CheckCircle className="h-4 w-4 text-green-500" />
            <AlertDescription>
              <div className="font-medium mb-2">Test Data Generated Successfully</div>
              <ul className="text-sm space-y-1">
                <li>• Created {results.summary.parks} park submissions</li>
                <li>• Created {results.summary.rides} ride submissions</li>
                <li>• Created {results.summary.companies} company submissions</li>
                <li>• Created {results.summary.rideModels} ride model submissions</li>
                {results.summary.photos > 0 && (
                  <li>• Created {results.summary.photos} photo submissions ({results.summary.totalPhotoItems || 0} photos)</li>
                )}
                <li className="font-medium mt-2">Time taken: {results.time}s</li>
              </ul>
            </AlertDescription>
          </Alert>
        )}

        <div className="flex gap-3">
          <Button onClick={handleGenerate} disabled={loading || selectedEntityTypes.length === 0}>
            <Beaker className="w-4 h-4 mr-2" />
            Generate Test Data
          </Button>

          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button variant="destructive" disabled={loading}>
                <Trash2 className="w-4 h-4 mr-2" />
                Clear All Test Data
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>Clear All Test Data?</AlertDialogTitle>
                <AlertDialogDescription>
                  This will permanently delete all test submissions marked with is_test_data: true. This action cannot be undone.
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>Cancel</AlertDialogCancel>
                <AlertDialogAction onClick={handleClear}>Clear Test Data</AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>

          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button variant="outline" disabled={loading} className="border-destructive text-destructive hover:bg-destructive/10">
                <AlertTriangle className="w-4 h-4 mr-2" />
                Emergency Cleanup (All Tables)
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>Emergency Cleanup - Delete ALL Test Data?</AlertDialogTitle>
                <AlertDialogDescription className="space-y-2">
                  <p className="font-medium text-destructive">⚠️ This is a nuclear option!</p>
                  <p>This will delete ALL records marked with is_test_data: true from ALL entity tables, including:</p>
                  <ul className="list-disc list-inside text-sm space-y-1">
                    <li>Parks, Rides, Companies (operators, manufacturers, etc.)</li>
                    <li>Ride Models, Photos, Reviews</li>
                    <li>Entity Versions, Edit History</li>
                    <li>Moderation Queue submissions</li>
                  </ul>
                  <p className="font-medium">This goes far beyond the moderation queue and cannot be undone.</p>
                  <p className="text-sm">Only use this if normal cleanup fails or you need to completely reset test data.</p>
                </AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>Cancel</AlertDialogCancel>
                <AlertDialogAction onClick={handleEmergencyCleanup} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
                  Delete All Test Data
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </div>
      </CardContent>
    </Card>
  );
}
