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

interface ModerationErrorBoundaryProps {
  children: ReactNode;
  submissionId?: string;
  fallback?: ReactNode;
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
}

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

type ErrorWithId = Error & { errorId: string };

/**
 * Error Boundary for Moderation Queue Components
 * 
 * Prevents individual queue item render errors from crashing the entire queue.
 * Shows user-friendly error UI with retry functionality.
 * 
 * Usage:
 * ```tsx
 * <ModerationErrorBoundary submissionId={item.id}>
 *   <QueueItem item={item} />
 * </ModerationErrorBoundary>
 * ```
 */
export class ModerationErrorBoundary extends Component<
  ModerationErrorBoundaryProps,
  ModerationErrorBoundaryState
> {
  constructor(props: ModerationErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
    };
  }

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

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log to database and get error ID for user reference
    const errorId = handleError(error, {
      action: 'Moderation queue item render error',
      metadata: {
        submissionId: this.props.submissionId,
        componentStack: errorInfo.componentStack,
      },
    });

    // Update state with error info
    this.setState({
      error: { ...error, errorId } as ErrorWithId,
      errorInfo,
    });

    // Call optional error handler
    this.props.onError?.(error, errorInfo);
  }

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

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

      // Default error UI
      return (
        <Card className="border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-900/10">
          <CardHeader className="pb-3">
            <CardTitle className="flex items-center gap-2 text-red-700 dark:text-red-300">
              <AlertCircle className="w-5 h-5" />
              Queue Item Error
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            <Alert variant="destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertTitle>Failed to render submission</AlertTitle>
              <AlertDescription>
                <div className="mt-2 space-y-2">
                  <p className="text-sm">
                    {this.state.error?.message || 'An unexpected error occurred'}
                  </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>
                  )}
                  {this.props.submissionId && (
                    <p className="text-xs text-muted-foreground font-mono">
                      Submission ID: {this.props.submissionId}
                    </p>
                  )}
                </div>
              </AlertDescription>
            </Alert>

            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={this.handleRetry}
                className="gap-2"
              >
                <RefreshCw className="w-4 h-4" />
                Retry
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => {
                  navigator.clipboard.writeText(
                    JSON.stringify({
                      error: this.state.error?.message,
                      stack: this.state.error?.stack,
                      submissionId: this.props.submissionId,
                    }, null, 2)
                  );
                }}
              >
                Copy Error Details
              </Button>
            </div>

            {process.env.NODE_ENV === 'development' && this.state.errorInfo && (
              <details className="text-xs">
                <summary className="cursor-pointer text-muted-foreground hover:text-foreground">
                  Show Component Stack
                </summary>
                <pre className="mt-2 overflow-auto p-2 bg-muted rounded text-xs">
                  {this.state.errorInfo.componentStack}
                </pre>
              </details>
            )}
          </CardContent>
        </Card>
      );
    }

    return this.props.children;
  }
}
