import React from 'react'
import Collapse from 'material-ui/transitions/Collapse'
import IconButton from '../IconButton'
import Button from '../Button'
import FontIcon from 'react-toolbox/lib/font_icon'
import Switch from '../Switch'
import theme from './theme.css'
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 (menuProps, e) {
    if (menuProps && menuProps.onClick) {
      menuProps.onClick(e)
    }
  }

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

  handleIconButton (actionProps, e) {
    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 }
    }
    let menuContainerStyle = {}
    menuProps.style = {
      ...menuProps.style,
      color: 'var(--nav-drawer-menu-color)'
    }
    if ((this.state.active && nested) || this.checkIsActive(m, selectedMenuValue)) {
      menuProps.style = {
        ...menuProps.style,
        backgroundColor: 'var(--nav-drawer-menu-background-active)',
        color: 'var(--nav-drawer-menu-color-active)'
      }
      menuContainerStyle.color = 'var(--nav-drawer-menu-color-active)'
    }
    let secondaryActionElement
    let secondaryActionStyle
    if (nested) {
      secondaryActionElement = this.state.active ? <FontIcon value='expand_less' /> : <FontIcon value='expand_more' />
      secondaryActionStyle = { pointerEvents: 'none', padding: '0 8px' }
    } else if (m.secondaryAction) {
      let action = m.secondaryAction
      let secondaryContent = action.content
      if (action.type === 'switch') {
        let actionProps = {...action.props}
        delete actionProps.onClick
        actionProps.onChange = this.handleSwitch.bind(this, action.checked, action.props)
        secondaryContent = (
          <Switch
            menuButton
            checked={action.checked}
            {...actionProps}
            style={{ color: 'var(--color-primary)' }}
          />
        )
        secondaryActionStyle = {
          marginRight: 8
        }
      } else if (action.type === 'iconButton') {
        let actionProps = {...action.props}
        delete actionProps.onClick
        actionProps.onClick = this.handleIconButton.bind(this, action.props)
        secondaryContent = (
          <IconButton
            menuButton
            style={{ color: 'var(--color-primary)' }}
            {...actionProps}
            icon={action.icon} />
        )
      }
      secondaryActionElement = secondaryContent
      menuProps.ripple = false
      menuProps.noAction = true
    }
    secondaryActionElement = (
      <div className={theme.secondaryAction} style={secondaryActionStyle}>
        {secondaryActionElement}
      </div>
    )
    let menuStyle = menuProps.style ? menuProps.style : {}
    menuStyle.height = 48
    menuStyle.borderRadius = 0
    return (
      <div key={key} className={theme.menuContainer} style={menuContainerStyle}>
        <Button label={m.text} icon={m.icon} full {...menuProps} style={menuStyle} menuButton />
        {secondaryActionElement}
      </div>
    )
  }

  render () {
    let menuBar = {...this.props}
    let items = []
    menuBar.menus.forEach((m, i) => {
      let menuProps = {...m.props}
      menuProps.onClick = this.handleMenuClick.bind(this, m.props)
      if (m.type === 'subheader') {
        let subheaderStyle = { color: 'inherit', ...menuProps.style }
        delete menuProps.style
        items.push(
          <div key={i} {...menuProps} className={theme.subheader} style={subheaderStyle}>
            {m.text}
          </div>
        )
      } 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 = <div>{items}</div>
    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
