import imgSrc from '@/assets/generic-error.png';
import { History } from '@mui/icons-material';
import { Box, Button, Container, Typography, useTheme } from '@mui/material';
import { TitleComponent, useTranslate } from 'ra-core';
import { Title, useResetErrorBoundaryOnLocationChange } from 'ra-ui-materialui';
import { ComponentType, ErrorInfo, HtmlHTMLAttributes, useCallback } from 'react';
import { FallbackProps } from 'react-error-boundary';

type ErrorBoundaryProps = InternalErrorProps & {
  errorComponent?: ComponentType<ErrorProps>;
  title?: TitleComponent;
  resetErrorBoundary?: null | (() => void);
};

function goBack() {
  window.history.go(-1);
}
function Error(props: ErrorBoundaryProps) {
  const { error, errorComponent: ErrorComponent, errorInfo, resetErrorBoundary, title } = props;
  const translate = useTranslate();
  const theme = useTheme();
  const isProduction = process.env.NODE_ENV === 'production';

  useResetErrorBoundaryOnLocationChange(resetErrorBoundary);

  const handleBack = useCallback(() => {
    goBack();
  }, []);

  if (ErrorComponent) {
    return <ErrorComponent error={error} errorInfo={errorInfo} title={title} />;
  }

  return (
    <Container>
      <Box
        sx={{
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'center',
          alignItems: 'center',
          py: 4,
          gap: 2
        }}
      >
        <Title title={title || 'Error'} />
        <Typography
          component="img"
          src={imgSrc}
          style={{ width: '100%', maxWidth: 350, marginTop: theme.spacing(3), marginBottom: theme.spacing(2) }}
          alt="oops!"
        />

        <Typography variant="h2" justifyContent={'center'} align="center" sx={{ mb: 2 }}>
          {translate(isProduction ? 'ra.page.error' : error.message, { _: error.message })}
        </Typography>

        <Button variant="contained" startIcon={<History sx={{ fontSize: 22 }} />} onClick={handleBack}>
          {translate('ra.action.back')}
        </Button>
      </Box>
    </Container>
  );
}

interface InternalErrorProps extends Omit<HtmlHTMLAttributes<HTMLDivElement>, 'title'>, FallbackProps, ErrorProps {
  className?: string;
}

interface ErrorProps extends Pick<FallbackProps, 'error'> {
  errorInfo?: ErrorInfo;
  title?: TitleComponent;
}

export { Error };
export type { ErrorBoundaryProps, ErrorProps, InternalErrorProps };
