import React, { Component, type ErrorInfo, type ReactNode } from 'react'

interface IFallbackProps {
  error: Error
}
interface Props {
  children?: ReactNode
  FallbackComponent?: React.ComponentType<IFallbackProps>
}

interface State {
  hasError: boolean
  error?: Error
}

class ErrorBoundary extends Component<Props, State> {
  constructor (props: Props) {
    super(props)
    this.state = {
      hasError: false,
      error: undefined

    }
  }

  public state: State = {
    hasError: false
  }

  public static getDerivedStateFromError (error: Error): State {
    // Update state so the next render will show the fallback UI.
    return {
      hasError: true,
      error
    }
  }

  public componentDidCatch (error: Error, errorInfo: ErrorInfo): void {
    console.log('Uncaught error:', error, errorInfo)
  }

  public render (): ReactNode {
    if (this.state.hasError) {
      return this.props.FallbackComponent !== undefined && this.state.error !== undefined
        ? <this.props.FallbackComponent error={this.state.error} />
        : <h1>There was an error</h1>
    }

    return this.props.children
  }
}

export default ErrorBoundary
