import * as React from 'react';
import { bindActionCreators, Dispatch } from 'redux';
import { connect } from 'react-redux';

import { InternalError } from 'mweb/common/components/errors/internalError';
import { NotFound } from 'mweb/common/components/errors/notFound';
import { RootState } from 'mweb/common/reducers/root';
import { errorResetErrorStatus } from 'mweb/common/actions/error';

export interface ErrorStatableDispatchProps {
  onWillUnmount: typeof errorResetErrorStatus;
}

export interface ErrorStatableOwnProps {
  notFound?: boolean;
  internalError?: boolean;
}

export interface ErrorStatableProps
  extends ErrorStatableDispatchProps,
    ErrorStatableOwnProps {}

export function ErrorStateWrapper<P>(
  WrappedComponent: React.ComponentType<P>,
): React.ComponentType<P & ErrorStatableOwnProps> {
  class ErrorStatable extends React.Component<P & ErrorStatableProps, {}> {
    componentWillUnmount(): void {
      this.props.onWillUnmount();
    }

    render(): JSX.Element {
      return (
        <div>
          {this.props.notFound ? <NotFound /> : null}
          {this.props.internalError && !this.props.notFound ? (
            <InternalError />
          ) : null}
          <div
            style={
              this.props.notFound || this.props.internalError
                ? { display: 'none' }
                : undefined
            }
          >
            <WrappedComponent {...this.props} />
          </div>
        </div>
      );
    }
  }

  function mapDispatchToProps(
    dispatch: Dispatch<RootState>,
  ): ErrorStatableDispatchProps {
    return bindActionCreators(
      {
        onWillUnmount: errorResetErrorStatus,
      },
      dispatch,
    );
  }
  return connect<{}, ErrorStatableDispatchProps, P & ErrorStatableOwnProps>(
    undefined,
    mapDispatchToProps,
  )(ErrorStatable);
}
