import React, { Component, ErrorInfo, ReactNode } from 'react';
import { AlertCircle, ArrowLeft, Home, RefreshCw } from 'lucide-react';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { handleError } from '@/lib/errorHandler';

interface EntityErrorBoundaryProps {
  children: ReactNode;
  entityType: 'park' | 'ride' | 'manufacturer' | 'designer' | 'operator' | 'owner';
  entitySlug?: string;
  fallback?: ReactNode;
}

interface EntityErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
  errorInfo: ErrorInfo | null;
}

type ErrorWithId = Error & { errorId: string };

export class EntityErrorBoundary extends Component<EntityErrorBoundaryProps, EntityErrorBoundaryState> {
  constructor(props: EntityErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
    };
  }

  static getDerivedStateFromError(error: Error): Partial<EntityErrorBoundaryState> {
    return {
      hasError: true,
      error,
    };
  }

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log to database and get error ID for user reference
    const errorId = handleError(error, {
      action: `${this.props.entityType} page error`,
      metadata: {
        entityType: this.props.entityType,
        entitySlug: this.props.entitySlug,
        componentStack: errorInfo.componentStack,
      },
    });

    this.setState({ errorInfo, error: { ...error, errorId } as ErrorWithId });
  }

  handleRetry = () => {
    this.setState({
      hasError: false,
      error: null,
      errorInfo: null,
    });
  };

  handleBackToList = () => {
    const listPages: Record<string, string> = {
      park: '/parks',
      ride: '/rides',
      manufacturer: '/manufacturers',
      designer: '/designers',
      operator: '/operators',
      owner: '/owners',
    };
    window.location.href = listPages[this.props.entityType] || '/';
  };

  handleGoHome = () => {
    window.location.href = '/';
  };

  getEntityLabel() {
    const labels: Record<string, string> = {
      park: 'Park',
      ride: 'Ride',
      manufacturer: 'Manufacturer',
      designer: 'Designer',
      operator: 'Operator',
      owner: 'Property Owner',
    };
    return labels[this.props.entityType] || 'Entity';
  }

  render() {
    if (this.state.hasError) {
      if (this.props.fallback) {
        return this.props.fallback;
      }

      const entityLabel = this.getEntityLabel();

      return (
        <div className="container mx-auto px-4 py-12">
          <Card className="max-w-2xl mx-auto border-destructive/50">
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-destructive">
                <AlertCircle className="w-5 h-5" />
                Failed to Load {entityLabel}
              </CardTitle>
              <CardDescription>
                {this.props.entitySlug 
                  ? `Unable to display ${entityLabel.toLowerCase()}: ${this.props.entitySlug}`
                  : `Unable to display this ${entityLabel.toLowerCase()}`}
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-4">
              <Alert variant="destructive">
                <AlertCircle className="h-4 w-4" />
                <AlertTitle>Error Details</AlertTitle>
                <AlertDescription>
                  <div className="mt-2 space-y-2">
                    <p className="text-sm">
                      {this.state.error?.message || `An unexpected error occurred while loading this ${entityLabel.toLowerCase()}`}
                    </p>
                    {(this.state.error as ErrorWithId)?.errorId && (
                      <p className="text-xs font-mono bg-destructive/10 px-2 py-1 rounded">
                        Reference ID: {(this.state.error as ErrorWithId).errorId.slice(0, 8)}
                      </p>
                    )}
                    <p className="text-xs text-muted-foreground">
                      This might be due to:
                    </p>
                    <ul className="text-xs text-muted-foreground list-disc list-inside space-y-1">
                      <li>The {entityLabel.toLowerCase()} no longer exists</li>
                      <li>Temporary data loading issues</li>
                      <li>Network connectivity problems</li>
                    </ul>
                  </div>
                </AlertDescription>
              </Alert>

              <div className="flex items-center gap-2 flex-wrap">
                <Button
                  variant="default"
                  size="sm"
                  onClick={this.handleRetry}
                  className="gap-2"
                >
                  <RefreshCw className="w-4 h-4" />
                  Try Again
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={this.handleBackToList}
                  className="gap-2"
                >
                  <ArrowLeft className="w-4 h-4" />
                  Back to {entityLabel}s
                </Button>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={this.handleGoHome}
                  className="gap-2"
                >
                  <Home className="w-4 h-4" />
                  Home
                </Button>
              </div>

              {import.meta.env.DEV && this.state.errorInfo && (
                <details className="text-xs">
                  <summary className="cursor-pointer text-muted-foreground hover:text-foreground">
                    Show Debug Info (Development Only)
                  </summary>
                  <pre className="mt-2 overflow-auto p-3 bg-muted rounded text-xs max-h-[300px]">
                    {this.state.errorInfo.componentStack}
                  </pre>
                </details>
              )}
            </CardContent>
          </Card>
        </div>
      );
    }

    return this.props.children;
  }
}
