import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { message } from 'amos-framework';
import StatusTextArea from './StatusTextArea';
import StatusTransformTabs from './StatusTransformTabs';
import {
  queryRuleSubObj,
  queryStatusRuleAction,
  queryAttributeAction,
  queryConditioneAction,
  addStatusObjectAction,
  updateStatusObjectAction
} from './../../services';

const attributeIndex = 1;
const conditionIndex = 2;
const resultIndex = 3;

class StatusTransformContent extends Component {

  static propTypes = {
    objId: PropTypes.any,
    linkId: PropTypes.any,
    closeDesigner: PropTypes.func,
    toggleReloadStage: PropTypes.func,
    sourceStatus: PropTypes.object,
    targetStatus: PropTypes.object
  };

  static defaultProps = {
    sourceStatus: {},
    targetStatus: {}
  };

  constructor(props) {
    super(props);
    this.state = {
      current: 0,
      rules: [],
      currentRulesIndex: 0,
      attributeList: [],
      conditionList: [],
      object: {},
      active: '',
      logical: '',
      statusTrans: {}
    };
  }

  componentDidMount() {
    this.onInitData(this.props);
  }

  componentWillReceiveProps(nextProps) {
    const { linkId } = nextProps;
    if (linkId !== this.props.linkId){
      this.onInitData(nextProps);
    }
  }

  onInitData = (props) => {
    const { objId, linkId } = props;
    objId && queryRuleSubObj(objId).then((data) =>{
      this.setState({ object: data || {} });
    });
    queryStatusRuleAction(linkId).then((data) =>{
      if (data) {
        const { pseudoCode } = data;
        let { rules, current, currentRulesIndex } = this.state;
        rules = [];
        pseudoCode.conditionList.map((e, index) => {
          e.map((item, i) => {
            const orWidth = i === 0 ? 'or' : 'with';
            rules.push({
              attributeId: item.propId,
              attribute: item.property,
              attributeName: item.propName,
              conditionId: item.relation,
              conditionName: item.relation,
              bizClassName: item.bizClassName,
              relationType: item.relationType,
              propType: item.propType,
              fact: item.fact,
              result: item.value,
              orWidth: index === 0 && i === 0 ? undefined : orWidth
            });
          });
        });
        currentRulesIndex = rules.length - 1;
        current = resultIndex;
        this.setState({ rules, current, currentRulesIndex, statusTrans: data });
      } else {
        this.setState({ current: 0, rules: [], currentRulesIndex: 0, active: '', logical: '', statusTrans: {} });
      }
    });
    objId && queryAttributeAction(objId).then((data) =>{
      this.setState({ attributeList: data || [] });
    });
    queryConditioneAction().then((data) =>{
      this.setState({ conditionList: data || [] });
    });
  }

  onAttributeClick = (item) => {
    const { rules, current, logical, currentRulesIndex } = this.state;
    if (current === 0) {
      const obj = { id: Date.now() };
      obj.attributeId = item.id;
      obj.attribute = item.name;
      obj.attributeName = item.displayName;
      obj.bizClassName = item.bizclassName;
      obj.fact = item.factId;
      obj.propType = item.dataType;
      obj.orWidth = currentRulesIndex === 0 || logical;
      rules.push(obj);
      this.setState({ rules, current: attributeIndex, currentRulesIndex: rules.length - 1 });
    } else {
      rules[currentRulesIndex].attributeId = item.id;
      rules[currentRulesIndex].attribute = item.name;
      rules[currentRulesIndex].attributeName = item.displayName;
      rules[currentRulesIndex].bizClassName = item.bizclassName;
      rules[currentRulesIndex].fact = item.factId;
      rules[currentRulesIndex].propType = item.dataType;
      this.setState({ rules });
    }
  }

  onConditionClick = (item) => {
    const { rules, current, currentRulesIndex } = this.state;
    if (current <= 1){
      this.setState({ current: conditionIndex });
    }
    rules[currentRulesIndex].conditionId = item.name;
    rules[currentRulesIndex].conditionName = item.displayName;
    rules[currentRulesIndex].relationType = item.type;
    this.setState({ rules });
  }

  onResultChange = (item) => {
    const { rules, current, currentRulesIndex } = this.state;
    if (current <= conditionIndex){
      this.setState({ current: resultIndex });
    }
    rules[currentRulesIndex].result = item.target.value;
    this.setState({ rules });
  }

  onLogicalChange = (item) => {
    const { rules } = this.state;
    this.setState({ current: 0, logical: item, currentRulesIndex: rules.length });
  }

  onReset = () => {
    this.setState({
      current: 0,
      rules: [],
      currentRulesIndex: 0,
      logical: ''
    });
  }

  onFinish = () => {
    const { rules, current, isLoading, statusTrans } = this.state;
    let { objId, targetStatus, linkId } = this.props;
    if (rules.length > 0 && current < 2) {
      message.danger('信息填写未完整');
      return;
    }
    if (rules.length === 0) {
      message.danger('必须填写条件');
      return;
    }
    if (isLoading) { return; }
    const newRules = [];
    if (rules.length > 0) {
      let res = [];
      rules.map(e => {
        if (e.orWidth === 'or') {
          newRules.push(res);
          res = [];
        }
        res.push({
          fact: e.fact,
          propId: e.attributeId,
          property: e.attribute,
          propName: e.attributeName,
          relation: e.conditionId,
          value: e.result || '',
          bizClassName: e.bizClassName,
          relationType: e.relationType,
          propType: e.propType
        });
      });
      res.length > 0 && newRules.push(res);
    }
    const triggerObj = {
      elementId: linkId,
      groupId: statusTrans.groupId,
      id: statusTrans.id,
      oid: objId,
      stateId: targetStatus.id,
      pseudoCode: JSON.stringify({
        conditionList: newRules
      })
    };
    this.setState({ isLoading: true });
    const req = statusTrans.id ? updateStatusObjectAction : addStatusObjectAction;
    req(triggerObj).then((data) =>{
      this.onReset();
      this.props.closeDesigner();
      this.props.toggleReloadStage(true);
      this.setState({ isLoading: false });
    }, (error) => {
      this.setState({ isLoading: false });
      message.danger(error || '保存失败');
    });
  }

  onRuleRemove = (index, obj) => {
    let { rules } = this.state;
    let newRules = rules.filter((e, i) => index > i || i >= (index + obj.length));
    if (newRules.length > 0) {
      newRules[0].orWidth = '';
    }
    this.setState({
      rules: newRules,
      current: newRules.length > 0 ? resultIndex : 0,
      currentRulesIndex: newRules.length > 0 ? newRules.length - 1 : 0
    });
  }

  onRuleClick = (index, obj) => {
    this.setState({ currentRulesIndex: index });
  }

  render() {
    const {
      current,rules,object, conditionList,
      attributeList, currentRulesIndex
    } = this.state;
    const { sourceStatus, targetStatus } = this.props;
    return (
      <div className="trigger-editor-content">
        <div className="trigger-editor-title">
          状态转换管理
        </div>
        <div className="trigger-editor-textarea">
          <StatusTextArea
            currentRulesIndex={currentRulesIndex}
            onRuleRemove={this.onRuleRemove}
            onRuleClick={this.onRuleClick}
            rules={rules}
            object={object}
            sourceStatus={sourceStatus.label}
            targetStatus={targetStatus.label}
          />
        </div>
        <StatusTransformTabs
          title={object.name}
          object={object}
          current={current}
          attributeList={attributeList}
          conditionList={conditionList}
          onAttributeClick={this.onAttributeClick}
          onConditionClick={this.onConditionClick}
          onResultChange={this.onResultChange}
          currentRules={rules[currentRulesIndex]}
          onAndClick={()=>this.onLogicalChange('with')}
          onOrClick={()=>this.onLogicalChange('or')}
          onFinishClick={this.onFinish}
        />
      </div>
    );
  }
}

export default StatusTransformContent;

