import React from "react";

import { Text } from "../Text";
import { View } from "../View";
import styles from "./styles";

type ErrorProps = {
  statusCode: number;
  title?: string;
};

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;
  };
};

const DefaultErrorComponent = ({ statusCode, title }: ErrorProps) => {
  return (
    <View style={styles.container}>
      <View style={styles.errorContainer}>
        <Text style={styles.title}>{statusCode}</Text>
        <Text style={styles.subTitle}>{title}</Text>
      </View>
    </View>
  );
};

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 = DefaultErrorComponent, children } = this.props;

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

    return children;
  }
}

export default ErrorBoundary;
