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

interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
  errorInfo?: React.ErrorInfo;
  retryCount: number;
}

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

export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      retryCount: 0
    };
  }

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error('🔥 ErrorBoundary caught an error:', error);
    console.error('📍 Error details:', errorInfo);
    
    // Enhanced logging for debugging
    console.group('🔍 Error Diagnostics');
    console.error('Error:', error);
    console.error('Component Stack:', errorInfo.componentStack);
    
    // Log performance/memory context
    if ((performance as any).memory) {
      const memory = (performance as any).memory;
      console.log('Memory Usage:', {
        used: `${Math.round(memory.usedJSHeapSize / (1024 * 1024))}MB`,
        total: `${Math.round(memory.totalJSHeapSize / (1024 * 1024))}MB`,
        limit: `${Math.round(memory.jsHeapSizeLimit / (1024 * 1024))}MB`
      });
    }
    
    console.log('Navigator Info:', {
      userAgent: navigator.userAgent,
      platform: navigator.platform,
      language: navigator.language,
      onLine: navigator.onLine
    });
    console.groupEnd();

    // Store error info for display
    this.setState({
      error,
      errorInfo
    });

    // Call custom error handler if provided
    if (this.props.onError) {
      this.props.onError(error, errorInfo);
    }
  }

  handleRetry = () => {
    console.log(`🔄 Retry attempt ${this.state.retryCount + 1}`);
    
    // Clear any timeouts and intervals (safer approach)
    const maxTimeouts = 1000;
    for (let i = 1; i <= maxTimeouts; i++) {
      clearTimeout(i);
      clearInterval(i);
    }
    
    // Reset error state and increment retry count
    this.setState(prevState => ({
      hasError: false,
      error: undefined,
      errorInfo: undefined,
      retryCount: prevState.retryCount + 1
    }));
  };

  handleReload = () => {
    console.log('🔄 Reloading page due to error');
    window.location.reload();
  };

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

      // Default error UI with detailed diagnostics
      return (
        <div className="min-h-screen bg-black text-green-400 font-mono p-8 border border-green-500 rounded-lg">
          <div className="max-w-4xl mx-auto space-y-6">
            {/* Header */}
            <div className="text-center border-b border-green-500 pb-4">
              <h1 className="text-2xl text-green-400 mb-2">⚠️ SYSTEM ERROR</h1>
              <p className="text-green-300">The oscilloscope encountered a critical error</p>
            </div>

            {/* Error Details */}
            <div className="bg-black/50 border border-green-500 p-4 rounded">
              <h2 className="text-xl text-green-400 mb-3">🔍 Error Analysis</h2>
              
              <div className="space-y-2 text-sm">
                <div>
                  <span className="text-green-300">Error Message:</span>
                  <div className="text-red-400 mt-1 p-2 bg-black rounded border border-red-500">
                    {this.state.error?.message || 'Unknown error'}
                  </div>
                </div>

                {this.state.error?.stack && (
                  <div>
                    <span className="text-green-300">Stack Trace:</span>
                    <pre className="text-xs text-yellow-300 mt-1 p-2 bg-black rounded border border-yellow-500 overflow-auto max-h-40">
                      {this.state.error.stack}
                    </pre>
                  </div>
                )}

                {this.state.errorInfo?.componentStack && (
                  <div>
                    <span className="text-green-300">Component Stack:</span>
                    <pre className="text-xs text-blue-300 mt-1 p-2 bg-black rounded border border-blue-500 overflow-auto max-h-40">
                      {this.state.errorInfo.componentStack}
                    </pre>
                  </div>
                )}

                <div>
                  <span className="text-green-300">Retry Count:</span> {this.state.retryCount}
                </div>

                {this.state.retryCount > 2 && (
                  <div className="bg-red-900/30 border border-red-500 p-3 rounded mt-4">
                    <p className="text-red-300 font-bold">⚠️ Multiple Retry Attempts</p>
                    <p className="text-red-200 text-sm mt-1">
                      This error may be persistent. Consider refreshing the page or using a smaller audio file.
                    </p>
                  </div>
                )}
              </div>
            </div>

            {/* System Info */}
            <div className="bg-black/50 border border-green-500 p-4 rounded">
              <h2 className="text-xl text-green-400 mb-3">💻 System Diagnostics</h2>
              
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
                <div>
                  <span className="text-green-300">Browser:</span>
                  <div className="text-white">{navigator.userAgent.split(' ')[0]}</div>
                </div>
                
                <div>
                  <span className="text-green-300">Platform:</span>
                  <div className="text-white">{(navigator as any).userAgentData?.platform || navigator.platform}</div>
                </div>

                {(performance as any).memory && (
                  <div>
                    <span className="text-green-300">Memory Usage:</span>
                    <div className="text-white">
                      {Math.round((performance as any).memory.usedJSHeapSize / (1024 * 1024))}MB / 
                      {Math.round((performance as any).memory.jsHeapSizeLimit / (1024 * 1024))}MB
                    </div>
                  </div>
                )}

                <div>
                  <span className="text-green-300">Online Status:</span>
                  <div className={navigator.onLine ? 'text-green-400' : 'text-red-400'}>
                    {navigator.onLine ? 'Online' : 'Offline'}
                  </div>
                </div>
              </div>
            </div>

            {/* Action Buttons */}
            <div className="flex flex-wrap gap-4 justify-center border-t border-green-500 pt-4">
              <button
                onClick={this.handleRetry}
                className="px-6 py-2 bg-green-600 text-white font-mono rounded hover:bg-green-500 transition-colors"
                disabled={this.state.retryCount >= 5}
              >
                🔄 Try Again ({this.state.retryCount}/5)
              </button>
              
              <button
                onClick={this.handleReload}
                className="px-6 py-2 bg-blue-600 text-white font-mono rounded hover:bg-blue-500 transition-colors"
              >
                🔄 Reload Page
              </button>
              
              <button
                onClick={() => window.open('/', '_self')}
                className="px-6 py-2 bg-yellow-600 text-white font-mono rounded hover:bg-yellow-500 transition-colors"
              >
                🏠 Go Home
              </button>
            </div>

            {/* Troubleshooting Tips */}
            <div className="bg-blue-900/20 border border-blue-500 p-4 rounded">
              <h3 className="text-lg text-blue-400 mb-2">💡 Troubleshooting Tips</h3>
              <ul className="text-sm text-blue-200 space-y-1">
                <li>• Try using a smaller audio file (&lt;500MB for testing)</li>
                <li>• Convert large FLAC files to MP3/OGG format</li>
                <li>• Close other browser tabs to free up memory</li>
                <li>• Try Chrome browser with --max-old-space-size=8192 flag</li>
                <li>• Check browser console for additional error details</li>
                <li>• Restart browser if memory usage is high</li>
              </ul>
            </div>
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}