import React, { Component, ReactNode } from 'react';

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
}

interface State {
  hasError: boolean;
  error: Error | null;
}

/**
 * Error Boundary component to catch and handle React errors
 * Prevents entire app from crashing when a component throws
 * 
 * @example
 * <ErrorBoundary fallback={<ErrorFallback />}>
 *   <MyComponent />
 * </ErrorBoundary>
 */
export class ErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
    };
  }

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    // Log error to console in development
    console.error('ErrorBoundary caught an error:', error, errorInfo);

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

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

  render() {
    if (this.state.hasError) {
      // Render custom fallback or default error UI
      if (this.props.fallback) {
        return this.props.fallback;
      }

      return (
        <div className="flex flex-col items-center justify-center p-8 bg-red-50 border border-red-200 rounded-lg">
          <div className="text-red-600 font-semibold mb-2">⚠️ Что-то пошло не так</div>
          <div className="text-sm text-red-500 mb-4">
            {this.state.error?.message || 'Произошла неизвестная ошибка'}
          </div>
          <button
            onClick={this.handleReset}
            className="px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition-colors"
          >
            Попробовать снова
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}

/**
 * Specific Error Boundary for Builder components
 */
export function BuilderErrorBoundary({ children }: { children: ReactNode }) {
  return (
    <ErrorBoundary
      fallback={
        <div className="flex flex-col items-center justify-center p-8 bg-yellow-50 border border-yellow-200 rounded-lg">
          <div className="text-yellow-700 font-semibold mb-2">⚠️ Ошибка в билдере</div>
          <div className="text-sm text-yellow-600 mb-4">
            Не удалось загрузить компонент. Попробуйте перезагрузить страницу.
          </div>
        </div>
      }
      onError={(error) => {
        // Could send to error tracking service here
        console.error('[Builder Error]:', error);
      }}
    >
      {children}
    </ErrorBoundary>
  );
}

/**
 * Specific Error Boundary for Preview component
 */
export function PreviewErrorBoundary({ children }: { children: ReactNode }) {
  return (
    <ErrorBoundary
      fallback={
        <div className="flex flex-col items-center justify-center h-full p-8 bg-gray-50">
          <div className="text-gray-600 font-semibold mb-2">⚠️ Ошибка превью</div>
          <div className="text-sm text-gray-500">
            Не удалось отобразить превью экрана
          </div>
        </div>
      }
    >
      {children}
    </ErrorBoundary>
  );
}
