/**
 * ErrorBoundary — catches render/runtime errors in the calendar tree and shows a
 * readable fallback instead of a blank white page.
 *
 * A white-screen-on-error calendar is unacceptable UX (the non-technical Apple member
 * would just see nothing). This boundary degrades gracefully and surfaces the error
 * text + component stack so failures are diagnosable in the field.
 */

import React from 'react'

interface ErrorBoundaryProps {
  children: React.ReactNode
}

interface ErrorBoundaryState {
  error: Error | null
  info: string | null
}

export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
  state: ErrorBoundaryState = { error: null, info: null }

  static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
    return { error }
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    // Log for DevTools / future telemetry; also kept in state for on-screen display.
    console.error('[CalendarShell crash]', error, info.componentStack)
    this.setState({ info: info.componentStack ?? null })
  }

  render() {
    if (this.state.error) {
      return (
        <div
          role="alert"
          style={{
            padding: '24px',
            fontFamily: 'system-ui, sans-serif',
            color: '#7f1d1d',
            background: '#fef2f2',
            height: '100dvh',
            overflow: 'auto',
            boxSizing: 'border-box',
          }}
        >
          <h2 style={{ marginTop: 0 }}>The calendar hit an error</h2>
          <p style={{ fontWeight: 600 }}>{String(this.state.error?.message ?? this.state.error)}</p>
          <pre
            style={{
              whiteSpace: 'pre-wrap',
              fontSize: '12px',
              background: '#fff',
              border: '1px solid #fecaca',
              borderRadius: '6px',
              padding: '12px',
            }}
          >
            {this.state.error?.stack}
            {this.state.info ? '\n\n--- component stack ---' + this.state.info : ''}
          </pre>
        </div>
      )
    }
    return this.props.children
  }
}
