import { Component } from 'react';
import * as ReactDOM from 'react-dom';
import { canUseDOM } from '../../helpers';
import { AlertGroupInline } from './AlertGroupInline';

export interface AlertGroupProps extends Omit<React.HTMLProps<HTMLUListElement>, 'className'> {
  /** Additional classes added to the AlertGroup */
  className?: string;
  /** Alerts to be rendered in the AlertGroup */
  children?: React.ReactNode;
  /** @beta Flag to indicate whether Alerts are animated upon rendering and being dismissed. This is intended
   * to remain false for testing purposes only.
   */
  hasAnimations?: boolean;
  /** Toast notifications are positioned at the top right corner of the viewport */
  isToast?: boolean;
  /** Turns the container into a live region so that changes to content within the AlertGroup, such as appending an Alert, are reliably announced to assistive technology. */
  isLiveRegion?: boolean;
  /** Determine where the alert is appended to */
  appendTo?: HTMLElement | (() => HTMLElement);
  /** Function to call if user clicks on overflow message */
  onOverflowClick?: () => void;
  /** Custom text to show for the overflow message */
  overflowMessage?: string;
  /** Adds an accessible label to the alert group. */
  'aria-label'?: string;
}

interface AlertGroupState {
  container: HTMLElement;
}

class AlertGroup extends Component<AlertGroupProps, AlertGroupState> {
  static displayName = 'AlertGroup';
  state = {
    container: undefined
  } as AlertGroupState;

  componentDidMount() {
    const container = document.createElement('div');
    const target: HTMLElement = this.getTargetElement();
    this.setState({ container });
    target.appendChild(container);
  }

  componentWillUnmount() {
    const target: HTMLElement = this.getTargetElement();
    if (this.state.container) {
      target.removeChild(this.state.container);
    }
  }

  getTargetElement() {
    const appendTo = this.props.appendTo;
    if (typeof appendTo === 'function') {
      return appendTo();
    }
    return appendTo || document.body;
  }

  render() {
    const {
      className,
      children,
      hasAnimations = false,
      isToast,
      isLiveRegion,
      onOverflowClick,
      overflowMessage,
      'aria-label': ariaLabel,
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      appendTo, // do not pass down to ul
      ...props
    } = this.props;
    const alertGroup = (
      <AlertGroupInline
        onOverflowClick={onOverflowClick}
        className={className}
        isToast={isToast}
        isLiveRegion={isLiveRegion}
        overflowMessage={overflowMessage}
        aria-label={ariaLabel}
        hasAnimations={hasAnimations}
        {...props}
      >
        {children}
      </AlertGroupInline>
    );
    if (!this.props.isToast) {
      return alertGroup;
    }

    const container = this.state.container;

    if (!canUseDOM || !container) {
      return null;
    }

    return ReactDOM.createPortal(alertGroup, container);
  }
}

export { AlertGroup };
