import React, {
  Fragment,
  Children,
  cloneElement,
  useRef,
  useEffect
} from 'react';
import PropTypes from 'prop-types';
import idgen from './idgen';
import cx from 'classnames';

const Dropdown = ({ children, className, trigger, options, ...props }) => {
  const _dropdownContent = useRef(null);

  useEffect(() => {
    const instance = M.Dropdown.init(
      document.querySelector(`[data-target="${props.id}"]`),
      options
    );

    return () => {
      instance && instance.destroy();
    };
  }, [options, props.id, children]);

  const renderTrigger = () =>
    cloneElement(trigger, {
      'data-target': props.id,
      className: cx(trigger.props.className, 'dropdown-trigger')
    });

  const renderItems = () =>
    Children.map((children || []).filter(Boolean), element => {
      if (element.type === 'li') {
        return element;
      } else if (
        element.type.name === 'Divider' ||
        element.type.displayName === 'Divider'
      ) {
        return <li key={idgen()} className="divider" tabIndex="-1" />;
      } else {
        return <li key={idgen()}>{element}</li>;
      }
    });

  return (
    <Fragment>
      {renderTrigger()}
      <ul
        {...props}
        className={cx('dropdown-content', className)}
        ref={_dropdownContent}
      >
        {renderItems()}
      </ul>
    </Fragment>
  );
};

export const dropdownOptions = PropTypes.shape({
  alignment: PropTypes.oneOf(['left', 'right']),
  autoTrigger: PropTypes.bool,
  constrainWidth: PropTypes.bool,
  container: PropTypes.node,
  coverTrigger: PropTypes.bool,
  closeOnClick: PropTypes.bool,
  hover: PropTypes.bool,
  inDuration: PropTypes.number,
  outDuration: PropTypes.number,
  onOpenStart: PropTypes.func,
  onOpenEnd: PropTypes.func,
  onCloseStart: PropTypes.func,
  onCloseEnd: PropTypes.func
});

Dropdown.propTypes = {
  id: PropTypes.string,
  /**
   * The node to trigger the dropdown
   */
  trigger: PropTypes.node.isRequired,
  children: PropTypes.node,
  className: PropTypes.string,

  /**
   * Options hash for the dropdown
   * <a target="_blank" href="http://materializecss.com/dropdown.html#options">http://materializecss.com/dropdown.html</a>
   */
  options: dropdownOptions
};

Dropdown.defaultProps = {
  id: `Dropdown_${idgen()}`,
  options: {
    alignment: 'left',
    autoTrigger: true,
    constrainWidth: true,
    container: null,
    coverTrigger: true,
    closeOnClick: true,
    hover: false,
    inDuration: 150,
    outDuration: 250,
    onOpenStart: null,
    onOpenEnd: null,
    onCloseStart: null,
    onCloseEnd: null
  }
};

export default Dropdown;

@@ -728,18 +728,17 @@
 Items = 
-()
+c
  =%3E%0A    
@@ -754,60 +754,155 @@
 map(
-(childr
+c, element =%3E %7B%0A      if (!elem
 en
+t
  %7C%7C 
-%5B%5D).filter(Boolean), element =%3E %7B%0A     
+element.type === 'li') %7B%0A        // Skip null, undefined, or li children%0A        return element;%0A      %7D else
  if 
@@ -911,36 +911,40 @@
 lement.type === 
-'li'
+Fragment
 ) %7B%0A        retu
@@ -935,38 +935,104 @@
 ) %7B%0A        
-return element
+// Recurse here for Fragments%0A        return renderItems(element.props.children)
 ;%0A      %7D el
@@ -1135,24 +1135,86 @@
 '%0A      ) %7B%0A
+        // Replace %3CDivider/%3E component with proper semantics%0A
         retu
@@ -1287,16 +1287,55 @@
  else %7B%0A
+        // Wrap child element in %3Cli/%3E%0A
         
@@ -1585,16 +1585,24 @@
 erItems(
+children
 )%7D%0A     

Allow for Dropdown children to also be Fragments.