import React, { Component, type ReactNode } from 'react'
import { HyperTwistButton } from './ui/HyperTwistButton'

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

interface State {
  hasError: boolean
  error?: Error
}

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, info: React.ErrorInfo) {
    console.error('[HyperTwist.ErrorBoundary] Caught error:', error, info.componentStack)
    this.props.onError?.(error, info)
  }

  private handleRetry = () => {
    this.setState({ hasError: false, error: undefined })
  }

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

      return (
        <div className="fatal-app-shell" role="alert" aria-live="assertive">
          <div className="card fatal-app-card">
            <p className="eyebrow">Runtime recovery</p>
            <h1>HyperTwist hit an unexpected browser error</h1>
            <p className="fatal-app-card__lede">
              The browser shell is still the operator and distribution surface, not the simulator itself.
              You can retry this view without claiming the desktop runtime is affected.
            </p>
            <div className="callout">
              <p>{this.state.error?.message || 'An unexpected error occurred loading this view.'}</p>
            </div>
            <div className="button-row">
              <HyperTwistButton type="button" onClick={this.handleRetry}>
                Retry this view
              </HyperTwistButton>
              <HyperTwistButton
                type="button"
                tone="ghost"
                onClick={() => window.location.assign('/')}
              >
                Return to homepage
              </HyperTwistButton>
            </div>
          </div>
        </div>
      )
    }

    return this.props.children
  }
}
