import React from 'react';
import { CircularProgress } from '@mui/material';

export default function LoadAsyncComponent<T extends React.ComponentType<any>>(
  importComponent: () => Promise<Record<string, T>>,
  key = 'default',
  showProgress = true
) {
  type Props = React.ComponentProps<T>;
  type State = {
    Component: React.ComponentType<any> | null;
    error: string | null;
  };

  class AsyncComponent extends React.Component<Props, State> {
    constructor(props: Props) {
      super(props);

      this.state = {
        Component: null,
        error: null,
      };
    }

    componentDidMount() {
      importComponent()
        .then((asyncModule) => this.setState({ Component: asyncModule[key] }))
        .catch((err) => this.setState({ error: `Failed to load async component: ${err.message}` }));
    }

    render() {
      const { Component, error } = this.state;

      if (error) {
        return error;
      }

      // eslint-disable-next-line no-nested-ternary
      return Component ? <Component {...this.props} /> : showProgress ? <CircularProgress color="primary" /> : null;
    }
  }

  return AsyncComponent;
}
