/**
 * Global Error Boundary with D1 Logging
 * Catches React errors and logs them to the backend
 */

const { Component } = React;

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
      errorId: null,
      isLogging: false,
    };
  }

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

  async componentDidCatch(error, errorInfo) {
    this.setState({ 
      error, 
      errorInfo,
      isLogging: true 
    });

    // Log error to backend
    try {
      const user = window.cloudRTCApp?.user || {};
      const token = localStorage.getItem('cloudrtc_token');

      const errorData = {
        message: error.toString(),
        stack: error.stack,
        errorInfo: errorInfo,
        componentStack: errorInfo.componentStack,
        url: window.location.href,
        userAgent: navigator.userAgent,
        userId: user.id,
        userEmail: user.email,
        timestamp: new Date().toISOString(),
        metadata: {
          pathname: window.location.pathname,
          search: window.location.search,
          hash: window.location.hash,
          referrer: document.referrer,
          screenResolution: `${window.screen.width}x${window.screen.height}`,
          viewportSize: `${window.innerWidth}x${window.innerHeight}`,
        },
      };

      const response = await fetch('/api/errors/log', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(token && { Authorization: `Bearer ${token}` }),
        },
        body: JSON.stringify(errorData),
      });

      if (response.ok) {
        const result = await response.json();
        console.log('[ERROR LOGGED]', result);
      }
    } catch (logError) {
      console.error('[ERROR LOGGING FAILED]', logError);
    } finally {
      this.setState({ isLogging: false });
    }

    // Log to console for development
    console.error('[ERROR BOUNDARY]', error, errorInfo);
  }

  handleReload = () => {
    window.location.reload();
  };

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

  render() {
    if (this.state.hasError) {
      return (
        <div className="min-h-screen bg-gray-900 text-white flex items-center justify-center p-4">
          <div className="max-w-2xl w-full bg-gray-800 rounded-lg shadow-xl p-8">
            {/* Error Icon */}
            <div className="flex justify-center mb-6">
              <div className="bg-red-500/20 rounded-full p-4">
                <i className="fas fa-exclamation-triangle text-red-500 text-5xl"></i>
              </div>
            </div>

            {/* Error Title */}
            <h1 className="text-3xl font-bold text-center mb-4">
              Oops! Something Went Wrong
            </h1>

            {/* Error Message */}
            <p className="text-gray-300 text-center mb-6">
              We're sorry, but something unexpected happened. 
              Our team has been notified and is working on a fix.
            </p>

            {/* Error Details (Collapsible) */}
            <details className="mb-6 bg-gray-900 rounded-lg p-4">
              <summary className="cursor-pointer text-blue-400 hover:text-blue-300 font-semibold">
                <i className="fas fa-code mr-2"></i>
                Technical Details
              </summary>
              <div className="mt-4 space-y-4">
                <div>
                  <div className="text-sm text-gray-400 mb-1">Error Message:</div>
                  <pre className="bg-black/50 p-3 rounded text-red-400 text-xs overflow-auto">
                    {this.state.error?.toString()}
                  </pre>
                </div>
                {this.state.error?.stack && (
                  <div>
                    <div className="text-sm text-gray-400 mb-1">Stack Trace:</div>
                    <pre className="bg-black/50 p-3 rounded text-gray-400 text-xs overflow-auto max-h-40">
                      {this.state.error.stack}
                    </pre>
                  </div>
                )}
                {this.state.errorInfo?.componentStack && (
                  <div>
                    <div className="text-sm text-gray-400 mb-1">Component Stack:</div>
                    <pre className="bg-black/50 p-3 rounded text-gray-400 text-xs overflow-auto max-h-40">
                      {this.state.errorInfo.componentStack}
                    </pre>
                  </div>
                )}
              </div>
            </details>

            {/* Logging Status */}
            {this.state.isLogging && (
              <div className="mb-6 bg-blue-500/20 border border-blue-500 rounded-lg p-3 flex items-center">
                <div className="animate-spin mr-3">
                  <i className="fas fa-circle-notch text-blue-400"></i>
                </div>
                <span className="text-blue-300">Logging error details...</span>
              </div>
            )}

            {/* Action Buttons */}
            <div className="flex flex-col sm:flex-row gap-3">
              <button
                onClick={this.handleReload}
                className="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-6 rounded-lg transition-colors flex items-center justify-center"
              >
                <i className="fas fa-redo mr-2"></i>
                Reload Page
              </button>
              <button
                onClick={this.handleGoHome}
                className="flex-1 bg-gray-700 hover:bg-gray-600 text-white font-semibold py-3 px-6 rounded-lg transition-colors flex items-center justify-center"
              >
                <i className="fas fa-home mr-2"></i>
                Go Home
              </button>
            </div>

            {/* Support Information */}
            <div className="mt-6 p-4 bg-gray-900 rounded-lg border border-gray-700">
              <p className="text-sm text-gray-400 text-center">
                <i className="fas fa-info-circle mr-2"></i>
                If this problem persists, please contact support with the error details above.
              </p>
            </div>
          </div>
        </div>
      );
    }

    return this.props.children;
  }
}

// Global error handler for non-React errors
window.addEventListener('error', async (event) => {
  const user = window.cloudRTCApp?.user || {};
  const token = localStorage.getItem('cloudrtc_token');

  const errorData = {
    message: event.message || 'Global JavaScript Error',
    stack: event.error?.stack || '',
    url: window.location.href,
    userAgent: navigator.userAgent,
    userId: user.id,
    userEmail: user.email,
    metadata: {
      filename: event.filename,
      lineno: event.lineno,
      colno: event.colno,
      type: 'global_error',
      timestamp: new Date().toISOString(),
    },
  };

  try {
    await fetch('/api/errors/log', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(token && { Authorization: `Bearer ${token}` }),
      },
      body: JSON.stringify(errorData),
    });
  } catch (logError) {
    console.error('[GLOBAL ERROR LOGGING FAILED]', logError);
  }
});

// Global promise rejection handler
window.addEventListener('unhandledrejection', async (event) => {
  const user = window.cloudRTCApp?.user || {};
  const token = localStorage.getItem('cloudrtc_token');

  const errorData = {
    message: event.reason?.message || 'Unhandled Promise Rejection',
    stack: event.reason?.stack || '',
    url: window.location.href,
    userAgent: navigator.userAgent,
    userId: user.id,
    userEmail: user.email,
    metadata: {
      reason: event.reason?.toString(),
      type: 'unhandled_rejection',
      timestamp: new Date().toISOString(),
    },
  };

  try {
    await fetch('/api/errors/log', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(token && { Authorization: `Bearer ${token}` }),
      },
      body: JSON.stringify(errorData),
    });
  } catch (logError) {
    console.error('[PROMISE REJECTION LOGGING FAILED]', logError);
  }
});

// Export for use in app
window.ErrorBoundary = ErrorBoundary;
