/**
 * Error Boundary component to catch React errors
 */

import { Component, type ReactNode } from 'react';
import { UiButton, UiCard, UiPage } from './ui/primitives';

interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: (error: Error, resetError: () => void) => ReactNode;
}

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

/**
 * Error boundary that catches React errors and displays a fallback UI
 */
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
    };
  }

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
    console.error('Error boundary caught error:', error, errorInfo);
  }

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

  render(): ReactNode {
    if (this.state.hasError && this.state.error) {
      if (this.props.fallback) {
        return this.props.fallback(this.state.error, this.resetError);
      }

      return (
        <UiPage className="flex min-h-screen items-center justify-center px-4">
          <UiCard className="w-full max-w-md p-6">
            <div className="mb-4 text-center">
              <div className="mb-4 text-6xl">⚠️</div>
              <h2 className="mb-2 text-2xl font-bold text-[var(--text-h)]">Something went wrong</h2>
              <p className="mb-4 text-[var(--text-dim)]">
                An unexpected error occurred. Please try refreshing the page.
              </p>
            </div>

            <details className="mb-4">
              <summary className="cursor-pointer text-sm font-medium text-[var(--text-dim)] transition-colors hover:text-[var(--text)]">
                Error details
              </summary>
              <pre className="mt-2 overflow-auto rounded bg-[var(--surface-muted)] p-3 text-xs text-[var(--color-error)]">
                {this.state.error.toString()}
                {this.state.error.stack && `\n\n${this.state.error.stack}`}
              </pre>
            </details>

            <div className="flex gap-3">
              <UiButton
                onClick={() => window.location.reload()}
                variant="primary"
                className="flex-1"
              >
                Refresh Page
              </UiButton>
              <UiButton
                onClick={this.resetError}
                className="flex-1"
              >
                Try Again
              </UiButton>
            </div>
          </UiCard>
        </UiPage>
      );
    }

    return this.props.children;
  }
}
