import NextError from "next/error";
import type { ErrorProps } from "next/error";
import React from "react";

type Props = {
  ErrorComponent?: React.ComponentType<ErrorProps>;
  children?: React.ReactNode;
  onError?: (error: Error, info: React.ErrorInfo) => void;
};

type State = {
  hasError: boolean;
  error: {
    status?: number;
    message?: string;
  };
};

class ErrorBoundary extends React.Component<Props, State> {
  static getDerivedStateFromError(error) {
    return { hasError: true, error };
  }

  state = {
    hasError: false,
    error: null,
  };

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    const { onError } = this.props;

    if (onError) {
      onError(error, info);
    }
  }

  render() {
    const { hasError, error } = this.state;
    const { ErrorComponent = NextError, children } = this.props;

    if (hasError) {
      return (
        <ErrorComponent statusCode={error.statusCode} title={error.message} />
      );
    }

    return children;
  }
}

export default ErrorBoundary;
