import { Component, type ErrorInfo, type ReactNode } from 'react';
import * as Sentry from '@sentry/react';
import { logger, getLogContext } from '@/utils/logger';
import { ErrorDisplay } from '@/components/ui/ErrorDisplay';

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
}

interface State {
  hasError: boolean;
  error?: Error;
  errorInfo?: ErrorInfo;
}

export class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error: Error): State {
    return { hasError: true, error };
  }

  override componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    this.setState({
      error,
      errorInfo,
    });

    // FIX #20: Logger l'erreur avec le logger structuré et Sentry
    const logContext = getLogContext();
    logger.error('[ErrorBoundary] React error caught', {
      error: error.message,
      stack: error.stack,
      componentStack: errorInfo.componentStack,
      ...logContext,
    });

    // Envoyer à Sentry avec contexte enrichi
    Sentry.captureException(error, {
      contexts: {
        react: {
          componentStack: errorInfo.componentStack,
        },
        application: logContext,
      },
    });
  }

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

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

      // Action 3.3.1.3: Use ErrorDisplay component for consistent error presentation
      return (
        <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 p-4">
          <div className="w-full max-w-md">
            <ErrorDisplay
              error={this.state.error || new Error('Une erreur inattendue s\'est produite')}
              variant="card"
              severity="error"
              size="lg"
              showDetails={import.meta.env.DEV}
              context={{
                component: 'ErrorBoundary',
                action: 'rendering component',
                componentStack: this.state.errorInfo?.componentStack,
              }}
              onRetry={this.handleReset}
              actions={[
                {
                  label: 'Retour à l\'accueil',
                  onClick: () => {
                    window.location.href = '/';
                  },
                  variant: 'outline',
                },
              ]}
            />
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}
