/*
* @Author: zhouningyi
* @Date: 2016-12-26 11:55:57
*/

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Utils        from './../../lib/utils';
import UiBase       from './../uiBase';
import Input        from './../Input/Base';
import TagIcon      from './../subcoms/TagIcon';
import {fade, emphasize} from 'material-ui/utils/colorManipulator';
import Popover      from 'material-ui/Popover';
import Menu         from 'material-ui/Menu';
import MenuItem     from 'material-ui/MenuItem';

function getStyles(props, context, state){
  const { palette } = context.muiTheme;
  let {textColor, borderColor, primary1Color} = palette;
  borderColor = state.isActive ? primary1Color : borderColor;
  return {
    root: {
      borderWidth: 1,
      borderColor,
      borderStyle: 'solid',
      boxSizing: 'border-box'
    },
    input: {
      color: textColor,
      border: 0,
      outline: 0,
      height: '100%',
      background: 'transparent',
      margin: '5px 8px',
      flexGrow: 1
    },
    menuItem:{
      backgroundColor: emphasize(context.muiTheme.menuItem.hoverColor, 0.3),
    }
  };
}

const isIn = (k, d) => {
  for(let i in d){
    if(_.isEqual(d[i], k)) return true;
  }
  return false;
};

const searchFilter = (k, ds) => {
  if(!ds) return null;
  if(!k)  return ds;
  return _.filter(ds, d => {
    if (typeof(d) === 'object') return d.value.toString().indexOf(k) !== -1 || d.name.toString().indexOf(k) !== -1;
    return d.toString().indexOf(k) !== -1;
  });
};

export default class MultiSelect extends UiBase {
  static propTypes = {
    data:           PropTypes.any.isRequired,
    onChange:       PropTypes.func.isRequired,
    onFinishChange: PropTypes.func
  }
  constructor(props: any) {
    super(props);
    this.state = {
      inputValue: '',
      isInputActive: false
    };
  }
  _genMenus(){
    const {inputValue} = this.state;
    const {value, validate} = this.state.data;
    const {options} = validate;
    const searched = searchFilter(inputValue, options);
    if (!searched) return null;
    const style = getStyles(this.props, this.context, this.state);
    const inputWrapper = this.refs.inputWrapper;
    let maxWidth, width, menuStyle = {};
    if(inputWrapper){
      width = maxWidth = inputWrapper.clientWidth + style.root.borderWidth * 2;
      menuStyle = {width, maxWidth};
    }
    return (
      <Popover
        open={this.state.isInputActive}
        anchorEl={this.refs.container}
        anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
        targetOrigin={{horizontal: 'left', vertical: 'top'}}
        onRequestClose={this.onBgClick}
        useLayerForClickAway={false}
        style={menuStyle}
      >
        <Menu>
          {_.map(searched, (d, k) => {
            const styleM = isIn(d, value) ? style.menuItem : {};
            Object.assign({}, menuStyle, styleM);
            const name  = typeof(d) === 'object' ? d.name  : d;
            const v     = typeof(d) === 'object' ? d.value : d;
            return (
              <MenuItem
                 key={name}
                 value={v} 
                 primaryText={name}
                 style={styleM}
                 onTouchTap={(e) => this.onMenuItemClick(e, d, k)}
              >
              </MenuItem>
            );
          })}
        </Menu>
      </Popover>
    );
  }
  onMenuItemClick = (e, v, k) => {
    const {value} = this.state.data;
    let bol = false;
    for(let i in value){
      if(_.isEqual(value[i], v)) {
        value.splice(i, 1);
        bol = true;
      }
    }
    if(!bol) value.push(v);
    this.onChange(value);
    this.setState({});
  }
  onInputChange = (e, v) => {
    this.setState({
      inputValue: e.nativeEvent.target.value,
    });
  }
  onChipDelete = (e, v) => {
    e.preventDefault();
    e.stopPropagation();
    const {value} = this.state.data;
    _.forEach(value, (d, i) => {
      if(_.isEqual(d, v)) value.splice(i, 1);
    });
    this.onChange(value);
    this.setState({});
  }
  _getWidthStyle(){
    const width = `${Math.floor(this.props.widthPhi * 100)}%`;
    return { width, maxWidth: width };
  }
  onInputClick = () => {
    this.setState({isInputActive: true});
  }
  onBgClick = () => {
    this.setState({isInputActive: !this.state.isInputActive});
  }
  _genTags(){
    const {value} = this.state.data;
    const height = this._getItemHeight() + 'px';
    let key, name;
    return _.map(value, (d, k) => {
      const name  = typeof(d) === 'object' ? d.name : d;
      const value = typeof(d) === 'object' ? d.value : d;
      return (
        <TagIcon
          key={name}
          id={name}
          style={{height, margin: '5px 5px'}}
          value={value}
          onDelete={(e) => this.onChipDelete(e, d)}
        >
         {name}
        </TagIcon>
      );
    });
  }
  _genInput(){
    const styles = getStyles(this.props, this.context, this.state);
    const height = this._getItemHeight();
    const style  = Object.assign(styles.input, {height, lineHeight: height});
    return (
      <input
        ref="input"
        style={styles.input}
        onChange={this.onInputChange}
        value={this.state.inputValue}
        onClick={this.onInputClick}
      />
    );
  }
  _getItemHeight(){
    return this._getDefaultHeight() * this.props.heightPhi;
  }
  _getElementsHeight () {
    return this.refs.inputWrapper ? this.refs.inputWrapper.offsetHeight : this._getDefaultHeight();
  }
  _getLineN(){
    return this.refs.inputWrapper ? Math.floor(this.refs.inputWrapper.clientHeight / this._getItemHeight()) : 1;
  }
  _getContainerStyle(){
    const style = _.cloneDeep(this.props.style);
    const lineN = this._getLineN();
    style.height = style.height * lineN;
    return style;
  }
  _getHeightStyle(){
    const {heightPhi} = this.props;
    let height = this._getElementsHeight();
    const margin = 0;
    return {height, margin};
  }
  componentDidUpdate(){
   this._focusInput();
  }
  //让input的光标固定下来
  _focusInput = () => {
    setTimeout(() => ReactDOM.findDOMNode(this.refs.input).focus(), 0);
  }
  _genUI(){
    let {onChange, onFinishChange, listN} = this.props;
    const {data} = this.state;
    let {validate, value} = data;
    if(!validate.options) validate.options = [value];

    const styles = getStyles(this.props, this.context, this.state);
    const rootStyle = Object.assign(this._getHeightStyle(), this._getWidthStyle());
    Object.assign(rootStyle, styles.root);
    
    return (
      <div 
        className="z_input-container"
        style={rootStyle}
        ref="container"
      >
        <div 
          className="z_input-wrapper-container"
          ref="inputWrapper"
        >
          {this._genTags()}
          {this._genInput()}
          {this._genMenus()}
        </div>
      </div>
    );
  }
}
