// @flow
import React from 'react';
import cn from 'classnames';

import './scss/modal.scss';

/** Props компонента Modal
  * @property {boolean} isOpen - открыто или закрыто модальное окно
  * @property {any} children - контент отображаемый в модальном окне
  */
type ModalProps = {
  children: any,
  isOpen: boolean,
};

/** State компонента Modal
  * @property {boolean} isOpen - открыто или закрыто модальное окно
  * @property {boolean} closing - состояние закрытия окна (для плавной анимации закрытия)
  */
type ModalState = {
  isOpen: boolean,
  closing: boolean,
};

/** Props компонента Header
  * @property {Function} toggle - коллбэк, меняющий состояние окна (открыто, закрыто)
  * @property {any} children - контент, отображаемый в компоненте Header модального окна
  */
type HeaderProps = {
  children: any,
  toggle: Function,
};

/** Props компонента Body
  * @property {any} children - контент, отображаемый в компоненте Body модального окна
  */
type BodyProps = { children: any };

/** Props компонента Footer
  * @property {any} children - контент, отображаемый в компоненте Footer модального окна
  */
type FooterProps = { children: any };

/** Компонент Header - шапка модального окна */
const Header = (props: HeaderProps) => (
  <div className='omni-modal__header'>
    <div className='omni-modal__header-title'>{props.children}</div>
    {props.toggle && <div className='omni-modal__close-button' onClick={props.toggle}>&times;</div>}
  </div>
);

/** Компонент Body - тело модального окна */
const Body = (props: BodyProps) => <div className='omni-modal__body'>{props.children}</div>;

/** Компонент Footer - нижний колонтитул модального окна */
const Footer = (props: FooterProps) => <div className='omni-modal__footer'>{props.children}</div>;

/** Компонент Modal - модальное окно
  * @example
  * <Modal isOpen={this.state.modal}>
  *   <Modal.Header toggle={this.toggle}>Заголовок</Modal.Header>
  *   <Modal.Body>
  *     Содержимое модального окна
  *     { this.state.isLoading && <div className='omni-modal__loader'/> }
  *   </Modal.Body>
  *   <Modal.Footer>Содержимое футера</Modal.Footer>
  * </Modal>
  */
export default class Modal extends React.Component<ModalProps, ModalState> {
  constructor(props: ModalProps) {
    super(props);
    this.state = {
      isOpen: props.isOpen,
      closing: false,
    };
  }

  static Header = Header;

  static Body = Body;

  static Footer = Footer;

  static defaultProps = {
    isOpen: false,
  };

  componentDidUpdate(prevProps: ModalProps) {
    if (prevProps.isOpen !== this.props.isOpen && !this.props.isOpen) {
      this.setState({ closing: true });
    }
    if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen) {
      this.setState({ isOpen: true });
    }
  }

  handleAnimation = () => {
    const { isOpen } = this.props;
    if (!isOpen) {
      this.setState({ isOpen: false, closing: false });
    }
  }

  render() {
    const { children } = this.props;
    const { isOpen, closing } = this.state;

    const modalClass = cn({
      'omni-ui-general': true,
      'omni-modal': true,
      'omni-modal_open': isOpen,
      'omni-modal_closing': closing,
    });
    return (
      <div
        className={modalClass}
        onTransitionEnd={this.handleAnimation}
      >
        <div className='omni-modal_layout'>
          <div className='omni-modal__content'>
            {isOpen && children}
          </div>
        </div>
      </div>
    );
  }
}
