import React from 'react'
import List, {
  ListItem,
  ListItemIcon,
  ListItemSecondaryAction,
  ListItemText,
  ListSubheader
} from 'material-ui/List'
import Collapse from 'material-ui/transitions/Collapse'
import ExpandLess from 'material-ui-icons/ExpandLess'
import ExpandMore from 'material-ui-icons/ExpandMore'
import Switch from 'material-ui/Switch'
import IconButton from 'material-ui/IconButton'
import PropTypes from 'prop-types'

class MenuList extends React.Component {
  constructor () {
    super()
    this.state = {
      active: false
    }
    this.lastMenuValue = null
  }

  componentWillMount () {
    if (this.props.nested) {
      let m = this.props.nested
      if (this.checkIsActive(m, this.props.selectedMenuValue)) {
        this.setState({
          active: true
        })
      }
    }
  }

  componentWillReceiveProps (nextProps) {
    let { selectedMenuValue } = nextProps
    if (nextProps.nested) {
      let m = nextProps.nested
      let active = this.checkIsActive(m, selectedMenuValue)
      if (this.state.active !== active) {
        this.setState({
          active: active
        })
      }
    }
    this.lastMenuValue = selectedMenuValue
  }

  handleMenuClick (disablePropagation, menuProps, e) {
    if (disablePropagation) { e.stopPropagation() }
    if (menuProps && menuProps.onClick) {
      menuProps.onClick(e)
    }
  }

  handleSwitch (disablePropagation, value, actionProps, e) {
    if (disablePropagation) { e.stopPropagation() }
    if (actionProps && actionProps.onClick) {
      actionProps.onClick(value, e)
    }
  }

  handleIconButton (disablePropagation, actionProps, e) {
    if (disablePropagation) { e.stopPropagation() }
    if (actionProps && actionProps.onClick) {
      actionProps.onClick(e)
    }
  }

  handleToggleNested (e) {
    e.stopPropagation()
    this.setState({
      active: !this.state.active
    })
  }

  checkIsActive (m, selectedMenuValue) {
    let active = m.value === selectedMenuValue
    if (m.type === 'nestedMenu') {
      m.menus.forEach((menu) => {
        let a = this.checkIsActive(menu, selectedMenuValue)
        if (a) {
          active = true
        }
      })
    }
    return active
  }

  generateMenu (m, key, menuProps, menuBar, nested) {
    let { activeBackgroundColor, activeColor, enableTypography, selectedMenuValue } = menuBar
    if (menuBar.gutters) {
      menuProps.style = { ...menuProps.style, marginTop: menuBar.gutters }
    }
    if ((this.state.active && nested) || this.checkIsActive(m, selectedMenuValue)) {
      menuProps.style = {
        ...menuProps.style,
        backgroundColor: typeof activeBackgroundColor !== 'undefined' ? activeBackgroundColor : 'rgba(250, 250, 250, 0.25)',
        color: typeof activeColor !== 'undefined' ? activeColor : 'inherit'
      }
    }
    let iconElement = m.icon ? (
      <ListItemIcon style={{ color: 'inherit' }}>
        {m.icon}
      </ListItemIcon>
    ) : ''
    let secondaryActionElement
    if (nested) {
      secondaryActionElement = this.state.active ? <ExpandLess /> : <ExpandMore />
    } else if (m.secondaryAction) {
      let action = m.secondaryAction
      let secondaryContent = action.content
      if (action.type === 'switch') {
        let actionProps = {...action.props}
        delete actionProps.onClick
        actionProps.onClick = this.handleSwitch.bind(this, m.disablePropagation, action.checked, action.props)
        secondaryContent = (
          <Switch
            checked={action.checked}
            {...actionProps} />
        )
      } else if (action.type === 'iconButton') {
        let actionProps = {...action.props}
        delete actionProps.onClick
        actionProps.onClick = this.handleIconButton.bind(this, m.disablePropagation, action.props)
        secondaryContent = (
          <IconButton
            {...actionProps}>
            {action.icon}
          </IconButton>
        )
      }
      secondaryActionElement = (
        <ListItemSecondaryAction>
          {secondaryContent}
        </ListItemSecondaryAction>
      )
    }
    return (
      <ListItem key={key} {...menuProps}>
        {iconElement}
        <ListItemText primary={m.text} disableTypography={!enableTypography}/>
        {secondaryActionElement}
      </ListItem>
    )
  }

  render () {
    let menuBar = {...this.props}
    let items = []
    menuBar.menus.forEach((m, i) => {
      let menuProps = {...m.props}
      menuProps.onClick = this.handleMenuClick.bind(this, ['subheader', 'divider'].indexOf(m.type) >= 0 || m.disablePropagation, m.props)
      if (m.type === 'subheader') {
        let subheaderStyle = { color: 'inherit', ...menuProps.style }
        delete menuProps.style
        items.push(
          <ListSubheader key={i} {...menuProps} style={subheaderStyle}>
            {m.text}
          </ListSubheader>
        )
      } else if (m.type === 'nestedMenu') {
        items.push(
          <MenuList
            key={i}
            {...this.props}
            menus={m.menus}
            nested={m} />
        )
      } else if (m.type === 'menu') {
        items.push(this.generateMenu(m, i, {...menuProps}, menuBar))
      }
    })
    let menuElement = <List>{items}</List>
    if (menuBar.nested) {
      let m = menuBar.nested
      let menuProps = {...m.props}
      menuProps.onClick = this.handleToggleNested.bind(this)
      let childContainerStyle = { paddingLeft: 16, ...m.childContainerStyle }
      menuElement = (
        <div>
          {this.generateMenu(m, 0, {...menuProps}, menuBar, true)}
          <Collapse in={this.state.active} transitionDuration='auto' unmountOnExit style={childContainerStyle}>
            {items}
          </Collapse>
        </div>
      )
    }
    return menuElement
  }
}

MenuList.propTypes = {
  menus: PropTypes.array,
  activeColor: PropTypes.string,
  enableTypography: PropTypes.bool,
  selectedMenuValue: PropTypes.string,
  gutters: PropTypes.any,
  nested: PropTypes.any
}

export default MenuList
