import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { observer, inject } from 'mobx-react';
import { Menu, Icon } from 'antd';
import classNames from 'classnames';
import './menu.less';

@withRouter
@inject('menu')
@observer
export default class extends Component {
  constructor(props) {
    super(props);
    this.rootSubmenuKeys = [];
    // selectedParent: 设置子菜单的父Id, selectedChildIndex: 设置子菜单的索引,主要用户选择的滑块滑动
    this.state = {
      openKeys: [],
      selectedKeys: [],
      selectedParent: '',
      selectedChildIndex: 0,
      signTop: 20,
      signStepHeight: 30,
      isHiddenMenu: false
    };
  }

  async componentWillMount() {
    await this.props.menu.getList();
    // 第一次获取数据是要进行菜单状态处理，防止处理事件响应完毕，菜单数据还没加载
    this.componentWillReceiveProps();
    this.props.menu.list.map(item => this.rootSubmenuKeys.push(item.id));
  }

  async componentDidMount() {
    this.resetSignData();
    window.addEventListener('resize', () => this.resetSignData());
  }

  // 当路由变化时，即组件的props发生了变化，会调用componentWillReceiveProps等生命周期钩子
  componentWillReceiveProps() {
    if (!this.hasMenu(this.props.history.location.pathname)) return;

    const { openKey, selectKey, selectedParent, selectedChildIndex } = this.getCurrentRouteKey();
    this.setState({
      openKeys: [openKey],
      selectedKeys: [selectKey],
      selectedParent,
      selectedChildIndex
    });
  }

  onOpenChange = openKeys => {
    const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1);
    if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
      this.setState({ openKeys });
    } else {
      this.setState({
        openKeys: latestOpenKey ? [latestOpenKey] : []
      });
    }
  }

  onSelect = selectMenu => {
    this.setState({
      selectedParent: selectMenu.item.props.parent,
      selectedChildIndex: selectMenu.item.props.index
    });
    this.setState({ selectedKeys: [selectMenu.key], isHiddenMenu: false });
    const { domEvent } = selectMenu;
    const { dataset } = domEvent.target;
    if (dataset.url) {
      window.location.href = dataset.url;
    } else {
      this.props.history.push(selectMenu.key);
    }
  };

  onSubMenuClick = (url, e) => {
    this.setState({ isHiddenMenu: true });
    if (url) {
      this.props.history.push(url);
    }
  }

  getCurrentRouteKey() {
    // 根据当前路由判断应该展开那些菜单
    const locationKey = this.props.history.location.pathname;
    let openKey = '';
    let selectedParent = '';
    let selectedChildIndex = 0;
    const selectKey = locationKey;
    for (let i = 0; i < this.props.menu.list.length; i++) {
      const item = this.props.menu.list[i];
      if (item.type === 'sub') {
        for (let j = 0; j < item.child.length; j++) {
          if (item.child[j].id === locationKey) {
            openKey = item.id;
            selectedParent = item.id;
            selectedChildIndex = j + 1;
            break;
          }
        }
      }
      if (openKey || item.id === locationKey) break;
    }
    openKey = openKey || locationKey;
    return { openKey, selectKey, selectedParent, selectedChildIndex };
  }

  resetSignData() {
    if (document.body.clientWidth <= 1600) {
      this.setState({ signTop: 20, signStepHeight: 30 });
    } else if (document.body.clientWidth > 1600 && document.body.clientWidth <= 1601) {
      this.setState({ signTop: 26, signStepHeight: 34 });
    } else {
      this.setState({ signTop: 32, signStepHeight: 40 });
    }
  }

  // 判断当前菜单列表是否有目标菜单
  hasMenu(menuKey) {
    let result = false;
    for (let i = 0; i < this.props.menu.list.length; i++) {
      const item = this.props.menu.list[i];
      if (item.type === 'sub') {
        for (let j = 0; j < item.child.length; j++) {
          if (item.child[j].id === menuKey) {
            result = true;
            break;
          }
        }
        if (result) {
          break;
        }
      } else if (item.id === menuKey) {
        result = true;
        break;
      }
    }
    return result;
  }

  render() {
    if (this.props.menu.list.length === 0) return null;
    return (
      <Menu
        mode="inline"
        inlineCollapsed={this.props.collapsed}
        className="menu"
        theme="dark"
        onSelect={this.onSelect}
        onOpenChange={this.onOpenChange}
        openKeys={this.state.openKeys}
        selectedKeys={this.state.selectedKeys}
      // defaultOpenKeys={this.state.openKeys}
      // defaultSelectedKeys={this.state.selectedKeys}
      >
        {this.props.menu.list.map(menu => {
          if (menu.type === 'sub') {
            return (
              <Menu.SubMenu
                className="select-sign"
                key={`${menu.id}`}
                onTitleClick={this.onSubMenuClick.bind(this, menu.url || '')}
                title={(
                  <span>
                    {
                      (() => {
                        if (menu.icon) {
                          if (menu.iconType) {
                            return <Icon type={menu.icon} />;
                          }
                          return <i className={`iconfont ${menu.icon}`} />;
                        }
                      })()
                    }
                    <span>{menu.name}</span>
                  </span>
                )}
              >
                <Menu.Item
                  className="ant-selected-sign"
                  disabled
                  style={{
                    visibility: (this.state.selectedParent === menu.id && !this.state.isHiddenMenu) ? 'visible' : 'hidden',
                    top: `${(this.state.selectedChildIndex - 1) * this.state.signStepHeight + this.state.signTop}px`
                  }}
                />
                {menu.child.map(sub => {
                  const menuItemClass = classNames('cus-sub-item-menu', { hidden: sub.hidden });
                  return (
                    <Menu.Item key={sub.id} url={sub.type} parent={menu.id} className={menuItemClass}>
                      <span>{sub.name}</span>
                    </Menu.Item>
                  );
                })}
              </Menu.SubMenu>
            );
          }
          if (menu.type === 'item' && !menu.hidden) {
            return (
              <Menu.Item
                key={menu.id}
                url={menu.type}
                data-url={menu.url}
              >
                {(() => {
                  if (menu.icon) {
                    if (menu.iconType) {
                      return <Icon type={menu.icon} />;
                    }
                    return <i className={`iconfont ${menu.icon}`} />;
                  }
                })()}
                <span>{menu.name}</span>
              </Menu.Item>
            );
          }
          return null;
        })}
      </Menu>
    );
  }
}
