import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import omit from 'lodash/omit';

import './dropdown-content.scss';

class Content extends Component {
  static propTypes = {
    /** @ignore */
    className: PropTypes.string,
    /** @ignore */
    children: PropTypes.node,
    active: PropTypes.bool,
    variant: PropTypes.string,
    reverse: PropTypes.bool,
    closePanel: PropTypes.func,
    itemsPerRow: PropTypes.oneOf([1, 2]),
    maxItems: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.number
    ])
  };

  static defaultProps = {
    className: undefined,
    children: [],
    active: false,
    variant: 'primary',
    reverse: false,
    closePanel: null,
    itemsPerRow: 1,
    maxItems: 100
  };

  state = {
    initial: true,
    height: null
  };

  componentDidMount() {
    this.computeHeight();
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.maxItems !== this.props.maxItems) {
      this.setState({ height: undefined, initial: true });
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (
      (this.props.active !== nextProps.active)
      || (this.state.initial !== nextState.initial)
      || (this.state.height !== nextState.height)
      || (this.props.children !== nextProps.children)
    );
  }

  componentDidUpdate() {
    if (this.state.initial) { this.computeHeight(); }
  }

  computeHeight = () => {
    if (this.props.maxItems < this.props.children.length) {
      this.setState({ height: this.container.getBoundingClientRect().height, initial: false });
    }
  }

  render() {
    const {
      active, children, reverse, className, maxItems, variant, closePanel, itemsPerRow
    } = this.props;
    const resultItemsPerRow = Math.min(itemsPerRow, 2);
    const childProps = { closePanel };
    if (variant === 'launcher') {
      childProps.variant = 'launcher';
    }
    return (
      <div
        styleName={classNames('content-wrapper', variant, { active, reverse })}
        className={className}
      >
        <div
          styleName={classNames('content', { [`content-${resultItemsPerRow}-items-per-row`]: resultItemsPerRow > 1 })}
          ref={container => { this.container = container; }}
          style={{ height: this.state.height || 'auto' }}
        >
          {React.Children.map(children, (child, i) => {
            if ((i < parseInt(maxItems, 10) && this.state.initial) || !this.state.initial) {
              if (React.isValidElement(child)) {
                if (typeof child.type === 'function') {
                  return React.cloneElement(child, childProps);
                }
                return React.cloneElement(child, omit(childProps, ['closePanel']));
              }
            }
            return child;
          })}
        </div>
      </div>
    );
  }
}

Content.componentName = 'Content';

export default Content;
