import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { visualProvided } from './VisualProvider';
import '../base';
import ButtonGroup from './Button.Group';
import styles from './Button.Menu.styl';
import IconButton from './IconButton';
import MediaQuery from './MediaQuery';
import Collapsible from './Collapsible';

class ButtonMenu extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      open: false
    };

    this.toggle = this.toggle.bind(this);
    this.close = this.close.bind(this);
  }

  toggle() {
    this.setState({
      open: !this.state.open
    });
  }

  close() {
    this.setState({
      open: false
    });
  }

  render() {
    const { collapsed, small, secondary, t, children } = this.props;
    const { open } = this.state;
    const classes = classNames({
      [styles.menu]: true,
      [styles.secondary]: secondary,
      [styles.small]: small,
      [styles.open]: open
    });

    const completelyCollapsed = (
      <div className={classes} onBlur={this.close}>
        <ButtonGroup>
          <ToggleButton small={small} secondary={secondary} t={t} open={open} toggle={this.toggle} />
        </ButtonGroup>
        <DropDown open={open} closeMenu={this.close}>
          {children}
        </DropDown>
      </div>
    );

    if (collapsed) {
      return completelyCollapsed;
    }

    /**
     * The partially collapsed view shows the first button directly and renders the rest in a submenu.
     * In the implementation below, we let react always render all buttons and then hide the ones we do not want using css.
     * This way, if some wrapped button in the menu decides not to render itself the menu will adapt appropiately.
     */

    const firstButton = (
      <div className={styles.hideAllButFirst}>
        {children}
      </div>
    );

    const otherButtons = (
      <div className={styles.hideFirst}>
        {children}
      </div>
    );

    const toggleButton = (
      <div className={styles.showLastIfMultipleSiblings}>
        {children}
        <ToggleButton small={small} t={t} secondary={secondary} open={open} toggle={this.toggle} />
      </div>
    );

    return (
      <div className={classes} onBlur={this.close}>

        <MediaQuery smallerThan medium>
          {completelyCollapsed}
        </MediaQuery>

        <MediaQuery medium>
          <ButtonGroup>
            {firstButton}
            {toggleButton}
          </ButtonGroup>
          <DropDown open={open} closeMenu={this.close}>
            {otherButtons}
          </DropDown>
        </MediaQuery>

      </div>
    );
  }

}

export default visualProvided(ButtonMenu);

ButtonMenu.propTypes = {
  children: PropTypes.node.isRequired,
  small: PropTypes.bool
};

ButtonMenu.defaultProps = {
  small: undefined
};

function DropDown({ children, open, closeMenu }) {
  const childrenAsArray = React.Children.toArray(children);

  return (
    <Collapsible
      open={open}
      className={styles.collapsible}
    >
      <ul
        className={styles.dropdown}
        /* prevent blur before onClick is triggererd. */
        onMouseDown={(e) => e.preventDefault()}
        onClick={closeMenu}
      >
        {childrenAsArray.map(
          (button, index) => (
            // eslint-disable-next-line react/no-array-index-key
            <li key={index}>{button}</li>
          )
        )}
      </ul>
    </Collapsible>
  );
}

function ToggleButton({ t, small, secondary, toggle, open }) {
  const classes = classNames({
    [styles.toggle]: true
  });

  return (
    <IconButton
      small={small}
      secondary={secondary}
      icon="doka-icon-functionshidden"
      className={classes}
      onClick={toggle}
    >
      {t('buttonMenuToggleLabel')}
    </IconButton>
  );
}
