import React from 'react'
import i18n from 'i18next'
import cls from 'classnames'
import treeActions from 'actions/tree'
import widgetStore from 'stores/widget'
import newEventStores from 'stores/newEvent'
import { getEventNodeById } from 'stores/funcs/newEvent'
import { nodeIsDyTransaction } from 'stores/funcs/nodeType'
import { isValidParamName } from 'stores/funcs/event/eventUtils'

export default class NodeParams extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      inParams: this.getInParams(),
      outParams: this.getOutParams(),
      title: this.getTitleName(),
      paramWarning: undefined
    }
    this.reloadAction = this.reloadAction.bind(this)
    this.onAddParam = this.onAddParam.bind(this)
    this.getInParams = this.getInParams.bind(this)
    this.getOutParams = this.getOutParams.bind(this)
    this.hasNoOutParams = this.hasNoOutParams.bind(this)
    this.getInParamsName = this.getInParamsName.bind(this)
    this.getOutParamsName = this.getOutParamsName.bind(this)
    this.getTitleName = this.getTitleName.bind(this)

    this.genAddButton = this.genAddButton.bind(this)
    this.genInput = this.genInput.bind(this)
    this.genError = this.genError.bind(this)
  }

  componentDidUpdate(preProps) {
    if (preProps.nodeId !== this.props.nodeId) {
      this.setState({
        inParams: this.getInParams(),
        outParams: this.getOutParams(),
        title: this.getTitleName(),
        paramWarning: undefined
      })
    }
  }

  reloadAction() {
    newEventStores.reloadAction(this.props.nodeId)
  }

  onAddParam(type) {
    let obj = { paramWarning: undefined }
    let params = undefined
    switch (type) {
      case 'in':
        params = this.state.inParams
        params.push('param' + (this.state.inParams.length + 1))
        obj.inParams = params
        break
      case 'out':
        params = this.state.outParams
        params.push('param' + (this.state.outParams.length + 1))
        obj.outParams = params
        break
    }
    this.setState(obj, () => {
      delete obj.paramWarning
      treeActions.changeNodeProps({
        nodeId: this.props.nodeId,
        props: obj
      })
      this.reloadAction()
    })
  }

  onDeleteParam(index, type) {
    let obj = { paramWarning: undefined }
    let params = undefined
    switch (type) {
      case 'in':
        params = this.state.inParams
        params.splice(index, 1)
        obj.inParams = params
        break
      case 'out':
        params = this.state.outParams
        params.splice(index, 1)
        obj.outParams = params
        break
    }
    this.setState(obj, () => {
      delete obj.paramWarning
      treeActions.changeNodeProps({
        nodeId: this.props.nodeId,
        props: obj
      })
      this.reloadAction()
    })
  }

  onChangeParam(index, type, applyChange, e) {
    let value = e && e.target ? e.target.value : e
    let obj = {}
    let params = undefined
    // 处理有问题字段
    if (applyChange && !isValidParamName(value)) {
      let errorValue = value
      if (value !== 'detail') {
        // outParam为detail时,不对其强行修改,只给出提示.其余情况将值改为paramX
        value = 'param' + (index + 1)
      }
      obj.paramWarning = {
        error: 'paramError',
        type: type,
        index,
        value: errorValue
      }
    } else {
      obj.paramWarning = undefined
    }
    switch (type) {
      case 'in':
        params = this.state.inParams
        params[index] = value
        obj.inParams = params
        break
      case 'out':
        params = this.state.outParams
        params[index] = value
        obj.outParams = params
        break
    }
    let nodeId = this.props.nodeId
    this.setState(obj, () => {
      if (applyChange) {
        delete obj.paramWarning
        treeActions.changeNodeProps({
          nodeId: nodeId,
          props: obj
        })
        this.reloadAction()
      }
    })
  }

  getInParams() {
    let inParams = []
    let node = getEventNodeById(this.props.nodeId)
    if (node) {
      inParams = node.props.inParams || inParams
    }
    return inParams
  }

  getOutParams() {
    let outParams = []
    let node = getEventNodeById(this.props.nodeId)
    if (node) {
      outParams = node.props.outParams || outParams
    }
    return outParams
  }

  hasNoOutParams() {
    let node = getEventNodeById(this.props.nodeId)
    return nodeIsDyTransaction(node && node.type)
  }

  getInParamsName() {
    let title = ''
    let node = getEventNodeById(this.props.nodeId)
    if (node && widgetStore.widget[node.type]) {
      let prop = widgetStore.widget[node.type].map.propsMap['inParams']
      title = prop.locale ? prop.locale[i18n.language] : prop.name
    }
    return title + '：'
  }

  getOutParamsName() {
    let title = ''
    let node = getEventNodeById(this.props.nodeId)
    if (node && widgetStore.widget[node.type]) {
      let prop = widgetStore.widget[node.type].map.propsMap['outParams']
      title = prop.locale ? prop.locale[i18n.language] : prop.name
    }
    return title + '：'
  }

  getTitleName() {
    let title = ''
    let node = getEventNodeById(this.props.nodeId)
    if (node && widgetStore.widget[node.type]) {
      let map = widgetStore.widget[node.type].map
      title = map.locale ? map.locale[i18n.language] : map.name
    }
    return title ? title + i18n.t('EventView.jenga_extra.defination') : title
  }

  genAddButton(type) {
    return (
      <button
        className="btn-clear btn-add-param"
        onClick={this.onAddParam.bind(this, type)}
      >
        <div className="icon">
          <span className="horizon" />
          <span className="vertical" />
        </div>
      </button>
    )
  }

  genInput(value, index, type) {
    let length =
      type === 'in' ? this.state.inParams.length : this.state.outParams.length
    let extraBtn = length - 1 === index ? this.genAddButton(type) : null
    return (
      <div
        className={cls('param-item f--hlc', {
          'param-item-left': index % 3 !== 0,
          'param-item-bottom': length > 3 && index < length - (length % 3 || 3)
        })}
        key={index}
      >
        <div className="item-name">
          {i18n.t('EventView.jenga_extra.param') + (index + 1)}
        </div>
        <div className="item-input-wrap f--hlc flex-1">
          <input
            value={value}
            onChange={this.onChangeParam.bind(this, index, type, false)}
            onBlur={this.onChangeParam.bind(this, index, type, true)}
          />
          <button
            className="btn-clear btn-delete-param"
            onClick={this.onDeleteParam.bind(this, index, type)}
          />
        </div>
        {extraBtn}
      </div>
    )
  }

  genError(type) {
    return this.state.paramWarning && this.state.paramWarning.type === type ? (
      <div className="param-warning f--hlc">
        {'* ' +
          i18n.t('EventView.jenga_extra.param') +
          (this.state.paramWarning.index + 1) +
          i18n.t('EventView.jenga_extra.setAs') +
          '"' +
          this.state.paramWarning.value +
          '"' +
          '，' +
          i18n.t('EventView.jenga_extra.' + this.state.paramWarning.error)}
      </div>
    ) : null
  }

  render() {
    return (
      <div className="jenga-node-params">
        <div
          className={cls(
            'params params-in',
            this.state.inParams.length > 0 ? 'f--h' : 'f--hlc'
          )}
        >
          <div
            className={cls(
              'params-title params-in-title',
              this.state.inParams.length > 3
                ? 'params-title-top f--h'
                : 'f--hlc'
            )}
          >
            {this.getInParamsName()}
          </div>
          <div>
            <div className="main-wrap f--hlc">
              {this.state.inParams.length === 0
                ? this.genAddButton('in')
                : this.state.inParams.map((param, index) => {
                    return this.genInput(param, index, 'in')
                  })}
            </div>
            {this.genError('in')}
          </div>
        </div>
        {this.hasNoOutParams() ? null : (
          <div
            className={cls(
              'params params-out',
              this.state.outParams.length > 0 ? 'f--h' : 'f--hlc'
            )}
          >
            <div
              className={cls(
                'params-title params-out-title',
                this.state.outParams.length > 3
                  ? 'params-title-top f--h'
                  : 'f--hlc'
              )}
            >
              {this.getOutParamsName()}
            </div>
            <div>
              <div className="main-wrap f--hlc">
                {this.state.outParams.length === 0
                  ? this.genAddButton('out')
                  : this.state.outParams.map((param, index) => {
                      return this.genInput(param, index, 'out')
                    })}
              </div>
              {this.genError('out')}
            </div>
          </div>
        )}
        <div className="params-title params-def-title">
          {this.getTitleName()}
        </div>
      </div>
    )
  }
}
