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

import React, { Component, PropTypes } from 'react';
import './index.css';
import Utils   from './../../lib/utils';

import Tag from './../Tag';

//
import _ from 'lodash';
import darkBaseTheme        from 'material-ui/styles/baseThemes/darkBaseTheme';
import MuiThemeProvider     from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme          from 'material-ui/styles/getMuiTheme';

const empty = () => null;

export default class Controls extends Component {
  static propTypes = {
    data:     PropTypes.array.isRequired,
    onChange: PropTypes.func.isRequired,
    editable: PropTypes.bool
  }
  static defaultProps = {
    data: [],
    onChange: (a, b, c) => console.log(),
    editable: true,
    compileFunction: false,
    direction: 'column',
    style: {
      height: 48,
    },
    bodyStyle: {
      flexGrow: 8,
    },
    nameStyle: {
      flexGrow: 2.5
    },
    endStyle: {
      flexGrow: 1
    },
    depthGrow: 0.4,
    widthPhi: 0.9,
    heightPhi: 0.7
  }
  constructor(props: any) {
    super(props);
    props = this.props;
    this.state = {
      data: Utils.check(_.cloneDeep(props.data))
    };
    this._resetData();
  }
  _resetData(){
    this.options = {};
  }
  componentWillReceiveProps(newprops){
    // if (_.isEqual(this.props.data, newprops.data)) return;
    const data = Utils.check(_.cloneDeep(newprops.data));
    this.setState({ data });
  }
  shouldComponentUpdate(newprops){
    return true;// _.isEqual(this.props.data, newprops.data);
  }
  //获取整体配置
  _getOptions = () => _.cloneDeep(this.options);
  _getValidation = (options) => Utils.mergeObject2Validation(_.cloneDeep(this.state.data), options)
  //根据输入的不同生成不同的ui界面
  _getSelectors = (ds, options, depth=0, chain='') => {
    if(!ds) return;
    const {props} = this;
    let prev = null;
    const depthNext = depth + 1;
    return _.map(ds, d => {
      //fixed
      const {children, key, handlerType, valueType, value, uiType, id, name} = d;
      let chainChild = chain === `` ? key : `${chain}.${key}`;
      //
      const _onChange = (data, valid) => {
        Object.assign(options, data);
        const value = _.values(data)[0];
        const diff = {data, value, chain: chainChild}
        Object.assign(d, valid);
        const optionsFinal = this._getOptions();
        const validationFinal = this._getValidation(optionsFinal);
        props.onChange(optionsFinal, diff, validationFinal);
      };
      const isFinish = (handlerType === 'finish');
      const onChange       =  isFinish ? empty : _onChange;
      const onFinishChange = !isFinish ? empty : _onChange;
      //
      let childrenOptions;
      if (valueType === 'group' && children) {
        childrenOptions = options[key] = {};
      } else {
        if (key) options[key] = value;
      }
      //
      const isBorder = d && prev && 
                       ((prev.valueType === 'group' && valueType === 'group') ||  
                       (prev.valueType !==  'group' && valueType !== 'group')) || false;
      prev = d;

      if (!Tag) return Utils.warn(`id: ${id}, 名字: ${name}的选择器不存在`);
      if (uiType === 'hidden') return;
      return (
        <Tag
          key={chainChild}
          data={Object.assign({}, d)}
          onChange={onChange}
          onFinishChange={onFinishChange}
          editable={props.editable}
          depth={depth}
          isBorder={isBorder}
          chain={chain}
          uiThemeId={props.uiThemeId}
          compileFunction={props.compileFunction}
          style={props.style}
          depthGrow={props.depthGrow}
          bodyStyle={props.bodyStyle}
          nameStyle={props.nameStyle}
          endStyle={props.endStyle}
          widthPhi={props.widthPhi}
          heightPhi={props.heightPhi}
          expand={props.expand}
        >
          { children && children.length > 0 ?  this._getSelectors(children, childrenOptions, depthNext, chainChild): null }
        </Tag>
      );
    });
  }
  renderColumn(){
    const options = this.options = {};
    return (
      <div className="_controls-panel">
        <div className="_controls-header"/>
        {this._getSelectors(this.state.data || [], options)}
        <div className="_controls-footer"/>
      </div>
    );
  }
  renderRow(){
    const options = this.options = {};
    return (
      <div className="z_controls-row-panel">
        {this._getSelectors(this.state.data || [], options)}
      </div>
    )
  }
  render(){
    const options = this.options = {};
    const {direction} = this.props;
    if(direction === 'column') return this.renderColumn();
    if(direction === 'row')    return this.renderRow();
    return null;
  }
}
