import React from 'react'
import cls from 'classnames'
import i18n from 'i18next'
import { Tooltip } from 'antd'
import { is } from 'immutable'
import newEventActions from 'actions/newEvent'
import newEventStores from 'stores/newEvent'
import widgetStore from 'stores/widget'
import userStore from 'stores/user'
import treeStores from 'stores/tree'
import uiStore from 'stores/ui'
import {
  getActionBlockObjNode,
  getEventBlockByBid,
  layerWidth,
  getBlockObj
} from 'stores/funcs/newEvent'
import { getNodeFromMap } from 'stores/funcs/tree'
import { getDbHeaderName } from 'stores/funcs/db'
import {
  getCloneNode,
  getDynamicParamName,
  getModuleInstanceNameLocale,
  smsTemplate
} from 'stores/funcs/event/methodUtils'
import {
  nodeIsDbNormal,
  nodeIsDbRouter,
  nodeIsDbVoteCandidate,
  nodeIsDynamoDb
} from 'src/stores/funcs/nodeType'
import { shallowEqualImmutable, cpJson } from 'utils/utils'
import { prop2id } from 'utils/convertModName'
import { isHySa } from 'utils/commons/ctrlHide'
import {
  getSpecialParamFormulaParams,
  getParamsAffectArea
} from 'src/components/common/formulaEditor/utils'
import propType from 'const/propType'
import { EVENT_BLOCK_TYPE, BLOCK_OP_TYPE } from 'src/const/const'
import { consFormulaShow } from 'src/utils/commons/ctrlHide'
// import {
//   getActionDbNodeType,
//   getActionDbId,
//   getNode
// } from './dbComs/actionDbFuncs'
// import BlockSelect from 'src/components/common/select/BlockSelect'
import BlockActionBoolean from 'src/components/common/event/normalComs/BlockActionBoolean'
// import DbSearchRange from 'src/components/common/event/dbComs/DbSearchRange'
// import BlockActionKeyValue from './normalComs/BlockActionKeyValue'
// import KeyValueJson from './normalComs/KeyValueJson'
// import BlockActionColRowValue from './normalComs/BlockActionColRowValue'
// import BlockActionNormalCons from './normalComs/BlockActionNormalCons'
// import BlockActionNormalOrders from './normalComs/BlockActionNormalOrders'
// import BlockActionObjSelect from './normalComs/BlockActionObjSelect'
// import BlockActionJsonParam from './normalComs/BlockActionJsonParam'
// import BlockActionJsonParamMult from './normalComs/BlockActionJsonParamMult'
// import DbConditionalSelector from './dbComs/DbConditionalSelector'
// import DbOrderSelector from './dbComs/DbOrderSelector'
// import DbNumColSelector from './dbComs/DbNumColSelector'
// import DbUpdateSelector from './dbComs/DbUpdateSelector'
// import DbColsSelector from './dbComs/DbColsSelector'
// import DbGroupByCols from './dbComs/DbGroupByCols'
// import DbGroupCols from './dbComs/DbGroupCols'
// import BlockActionDbRange from './dbComs/DbRangeSelector'
// import DyQueryCons from './dyComs/DyQueryCons'
// import DyUpdate from './dyComs/DyUpdate'
// import DyCons from './dyComs/DyCons'
// import SubChildren from './subChildren/SubChildren'
import FormulaEditor from 'src/components/common/formulaEditor/EventFormulaEditor'
import EventJsonEditor from 'src/components/common/formulaEditor/EventJsonEditor'
import iconStrObj from 'src/assets/icons/iconsStr'

export default class BlockActionMethodParamItem extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      param: this.getParamItem(props.param),
      value: this.getParamValue(),
      widthDelta: uiStore.jengaViewWidthDelta
    }

    this.onEventChange = this.onEventChange.bind(this)
    this.onUiChange = this.onUiChange.bind(this)
    this.onChangeValue = this.onChangeValue.bind(this)
    // this.getObject = this.getObject.bind(this)
    this.getParamValue = this.getParamValue.bind(this)
    this.getName = this.getName.bind(this)
    this.getParamName = this.getParamName.bind(this)
    this.getParamPropsMap = this.getParamPropsMap.bind(this)
    this.getCloneNodeId = this.getCloneNodeId.bind(this)
    this.getParamItem = this.getParamItem.bind(this)
    this.getParamNameStyle = this.getParamNameStyle.bind(this)
    this.getParamValueStyle = this.getParamValueStyle.bind(this)
    this.getWholeParamStyle = this.getWholeParamStyle.bind(this)
    this.paramValueCom = this.paramValueCom.bind(this)
    this.getItemValueCom = this.getItemValueCom.bind(this)

    this.getItemTips = this.getItemTips.bind(this)
    this.getItemPlaceholder = this.getItemPlaceholder.bind(this)
    // this.paramIsInDbSearch = this.paramIsInDbSearch.bind(this)

    this.getOptionFonts = this.getOptionFonts.bind(this)
    this.getOptionIcons = this.getOptionIcons.bind(this)
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (
      !shallowEqualImmutable(this.props, nextProps) ||
      !shallowEqualImmutable(this.state, nextState)
    )
  }

  componentDidMount() {
    this.unsubscribe = newEventStores.listen(this.onEventChange)
    this.unsubscribeUI = uiStore.listen(this.onUiChange)
  }

  componentWillUnmount() {
    this.unsubscribe()
    this.unsubscribeUI()
  }

  componentDidUpdate(preProps) {
    let param = this.getParamItem()
    if (!is(this.state.param, param)) {
      this.setState({
        param: param
      })
    }
  }

  onEventChange(status) {
    let obj = {}
    if (status) {
      if (
        status.types.includes('changeActionBlockParamsValue') &&
        this.props.bid === status.data.affectBlockId &&
        status.data.index === this.props.index
      ) {
        let value = this.getParamValue()
        if (!is(this.state.value, value)) {
          obj.value = value
        } else {
          obj.value = { ...value }
        }
      }
    }
    if (Object.keys(obj).length > 0) {
      this.setState(obj)
    }
  }

  onUiChange(status) {
    if (status && status.types) {
      if (status.types.includes('changeJengaViewWidthDelta')) {
        if (status.data.jengaViewWidthDelta !== this.state.widthDelta) {
          this.setState({
            widthDelta: status.data.jengaViewWidthDelta
          })
        }
      }
    }
  }

  getParamValue() {
    // 获取param的值
    let value = null
    let eventNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, eventNodeId)
    let paramName = this.props.param.name
    switch (block.op) {
      case BLOCK_OP_TYPE.SET:
        let args_set = block.args
        let targetParam_set = args_set.find(item => {
          return item.op === 'prop' && item.val === paramName
        })
        if (
          targetParam_set &&
          targetParam_set.args &&
          targetParam_set.args[0]
        ) {
          let op = targetParam_set.args[0].op
          value =
            op === 'var'
              ? targetParam_set.args[0].expVal
              : targetParam_set.args[0].val
        }
        break
      case BLOCK_OP_TYPE.CALL:
        let args_call = block.args
        let targetParam_call = args_call.find(item => {
          return item.key === paramName
        })
        if (targetParam_call) {
          let op = targetParam_call.op
          value = op === 'var' ? targetParam_call.expVal : targetParam_call.val
        }
        break
      case BLOCK_OP_TYPE.LET:
        if (
          block.args &&
          block.args[0] &&
          block.args[0].op === 'call' &&
          block.args[0].args
        ) {
          let args_let = block.args[0].args
          let targetParam_let = args_let.find(item => {
            return item.key === paramName
          })
          if (targetParam_let) {
            let op = targetParam_let.op
            value = op === 'var' ? targetParam_let.expVal : targetParam_let.val
          }
        }
        break
    }
    return value
  }

  onChangeValue(index, value, addRecord) {
    let paramName = this.state.param.name
    let actionName = this.getName()
    let reloadMethod = false
    // 引起参数变化
    if (
      (actionName === 'clone' && paramName === 'cloneId' && index === 0) ||
      (['sendSMS', 'sendSMS_stage'].indexOf(actionName) >= 0 &&
        paramName === 'template' &&
        index === 1) ||
      (['sendTemplate'].indexOf(actionName) >= 0 && paramName === 'mode') ||
      (['shareApp'].indexOf(actionName >= 0) && paramName === 'type') ||
      (['toDataURL'].indexOf(actionName) >= 0 && paramName === 'imgType') ||
      (['browsePic', 'browseMutiPic'].indexOf(actionName) >= 0 &&
        paramName === 'outputBase64') ||
      (['createPayInfo', 'refund', 'orderquery'].indexOf(actionName) >= 0 &&
        paramName === 'mode')
    ) {
      reloadMethod = true
    }
    let obj = {
      nodeId: this.props.eventNodeId || newEventStores.curEventNodeId,
      blockId: this.props.bid,
      index,
      paramName,
      value,
      reloadMethod
    }
    this.setState({
      value: value
    })
    this.forceUpdate()
    newEventActions.changeActionParamValue(obj)
  }

  // getObject() {
  //   let _obj = null
  //   let block = getEventBlockByBid(this.props.bid)
  //   if (block) {
  //     _obj = block.object
  //   }
  //   return _obj
  // }

  getName() {
    return this.props.actionName ? this.props.actionName || null : null
  }

  getParamName() {
    let name = this.state.param.name
    let locale = this.state.param.locale
    let isDbHeader = this.state.param.isDbHeader
    let isMini = this.state.param.mini
    let isProp = this.state.param.isProp
    let actionName = this.getName()
    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, nodeId)
    let obj = getBlockObj({ block })
    if (block && obj && actionName) {
      let node = getActionBlockObjNode({
        obj,
        nodeId
      })
      if (node) {
        if (isMini) {
          name = getModuleInstanceNameLocale({
            nodeId: node.id,
            type: 'props',
            name: prop2id(name)
          })
        // } else if (actionName === 'clone' && this.props.index >= 3) {
        //   let cloneNode = getCloneNode(this.props.bid)
        //   if (cloneNode) {
        //     let propsMap =
        //       widgetStore.widget[cloneNode.type] &&
        //       widgetStore.widget[cloneNode.type].map &&
        //       widgetStore.widget[cloneNode.type].map.propsMap
        //     if (propsMap && propsMap[name] && propsMap[name].locale) {
        //       name = propsMap[name].locale[i18n.language]
        //     }
        //   }
        // } else if (
        //   ['sendSMS', 'sendSMS_stage'].indexOf(actionName) >= 0 &&
        //   this.props.index >= 2
        // ) {
        //   if (block.action && block.action.params && block.action.params[1]) {
        //     let tempInfo = smsTemplate[block.action.params[1].value]
        //     if (tempInfo && tempInfo.args) {
        //       let param = tempInfo.args.find(arg => {
        //         return arg.name === name
        //       })
        //       if (param && param.locale) {
        //         name = param.locale[i18n.language]
        //       }
        //     }
        //   }
        } else if (actionName === 'setProps' || isProp) {
          let propsMap =
            widgetStore.widget[node.type] &&
            widgetStore.widget[node.type].map &&
            widgetStore.widget[node.type].map.propsMap
          if (propsMap && propsMap[name] && propsMap[name].locale) {
            name = propsMap[name].locale[i18n.language]
          }
        // } else if (isDbHeader) {
        //   let actionDbNodeType = getActionDbNodeType({
        //     node,
        //     bid: this.props.bid
        //   })
        //   if (nodeIsDynamoDb(actionDbNodeType)) {
        //     let dbInfo = this.props.dbInfo
        //     let dbCols = dbInfo ? dbInfo.dbCols || [] : undefined
        //     if (dbCols) {
        //       let item = dbCols.find(col => {
        //         return col.name === name
        //       })
        //       if (item) {
        //         if (isDbHeader === 'internal') {
        //           let header = { name: name, internal: true }
        //           let transName =
        //             'DbView.dyHeader.' +
        //             getDbHeaderName(header, actionDbNodeType)
        //           if (i18n.exists(transName)) {
        //             name = item.alias
        //               ? item.alias +
        //                 i18n.t('DbParamPanel.left_bracket') +
        //                 i18n.t(transName) +
        //                 i18n.t('DbParamPanel.right_bracket')
        //               : i18n.t(transName)
        //           }
        //         } else {
        //           name = item.alias
        //         }
        //       }
        //     }
        //   } else {
        //     if (isDbHeader === 'internal') {
        //       let header = { name: name, internal: true }
        //       let transName =
        //         'DbView.header.' + getDbHeaderName(header, actionDbNodeType)
        //       if (i18n.exists(transName)) {
        //         name = i18n.t(transName)
        //       }
        //     } else if (locale) {
        //       name = locale[i18n.language] || name
        //     }
        //   }
        } else {
          if (['setObjTransition', 'tweenTo'].indexOf(actionName) >= 0) {
            let propsMap =
              widgetStore.widget[node.type] &&
              widgetStore.widget[node.type].map &&
              widgetStore.widget[node.type].map.propsMap
            if (propsMap && propsMap[name] && propsMap[name].locale) {
              name = propsMap[name].locale[i18n.language]
            }
          }
          let actionsMap =
            widgetStore.widget[node.type] &&
            widgetStore.widget[node.type].map &&
            widgetStore.widget[node.type].map.methodsMap
          if (
            actionsMap &&
            actionsMap[actionName] &&
            actionsMap[actionName].params
          ) {
            let params = actionsMap[actionName].params
            // 由于tweenTo在原方法修改，故在不修改方法的前提下处理，只取最后2个参数
            if (actionName === 'tweenTo' && params.length >= 2) {
              params = [params[params.length - 2], params[params.length - 1]]
            }
            let param = params.find(param => {
              return param.name === name
            })
            if (param && param.locale) {
              name = param.locale[i18n.language] || name
            }
            // if (nodeIsDynamoDb(node.type)) {
            //   let dbInfo = this.props.dbInfo
            //   let dbCols = dbInfo ? dbInfo.dbCols || [] : undefined
            //   name = getDynamicParamName(
            //     node.type,
            //     dbCols,
            //     actionName,
            //     this.state.param.name,
            //     name
            //   )
            // }
          }
        }
      }
    }
    return name
  }

  getParamPropsMap() {
    let paramName = this.state.param.name
    let isProp = this.state.param.isProp
    let actionName = this.getName()

    let nodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, nodeId)
    let obj = getBlockObj({ block })
    if (block && obj && actionName) {
      let node = getActionBlockObjNode({
        obj,
        nodeId
      })
      if (node) {
        if (actionName === 'setProps' || isProp) {
          let propsMap =
            widgetStore.widget[node.type] &&
            widgetStore.widget[node.type].map &&
            widgetStore.widget[node.type].map.propsMap
          return propsMap[paramName]
        } else {
          let actionsMap =
            widgetStore.widget[node.type] &&
            widgetStore.widget[node.type].map &&
            widgetStore.widget[node.type].map.methodsMap
          if (
            actionsMap &&
            actionsMap[actionName] &&
            actionsMap[actionName].params
          ) {
            let params = actionsMap[actionName].params
            return params.find(param => {
              return param.name === paramName
            })
          }
        }
      }
    }
  }

  getCloneNodeId() {
    let node = getCloneNode(this.props.bid)
    if (node) {
      return node.id
    }
    return undefined
  }

  getParamItem(param) {
    return param !== undefined ? param : this.props.param
  }

  getParamNameStyle() {
    const groupLayer = this.props.groupLayer > 0 ? this.props.groupLayer : 0
    const nestingLayer =
      this.props.nestGroupLayer > 0 ? this.props.nestGroupLayer - 1 : 0
    const extraGapGroupLayer =
      this.props.extraGapGroupLayer > 0
        ? (this.props.extraGapGroupLayer - 1) * 2
        : 0
    const originWidth =
      324 - (groupLayer + nestingLayer) * 2 - extraGapGroupLayer
    let width = layerWidth({
      originWidth: originWidth,
      decreaseFactor: 21,
      layer: this.props.layer
    })
    return {
      width: width + 'px',
      minWidth: width + 'px'
    }
  }

  getParamValueStyle() {
    return {
      width: 275 + this.state.widthDelta + 'px'
    }
  }

  getWholeParamStyle() {
    let width = layerWidth({
      originWidth: 608 + this.state.widthDelta,
      decreaseFactor: 21,
      layer: this.props.layer
    })
    return {
      width: width + 'px',
      minWidth: width + 'px'
    }
  }

  // paramIsInDbSearch() {
  //   let result = false
  //   let node = getNode({ bid: this.props.bid, actionName: this.getName() })
  //   if (
  //     node &&
  //     (nodeIsDbNormal(node.type) ||
  //       nodeIsDbRouter(node.type) ||
  //       nodeIsDbVoteCandidate(node.type))
  //   ) {
  //     let block = getEventBlockByBid(this.props.bid)
  //     if (
  //       block &&
  //       block.object &&
  //       block.type === EVENT_BLOCK_TYPE.ACTION &&
  //       block.action &&
  //       [
  //         'dbSmartSearch_stage',
  //         'dbSmartSearch',
  //         'dbCustomizeSearch_stage',
  //         'dbCustomizeSearch'
  //       ].indexOf(block.action.name) >= 0
  //     ) {
  //       result = true
  //     }
  //   }
  //   return result
  // }

  paramIsPath() {
    let result = false
    let eventNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, eventNodeId)
    let obj = getBlockObj({ block })
    let actionName = this.getName()
    if (
      block &&
      obj &&
      actionName &&
      ['setCusPathValue'].indexOf(actionName) >= 0 &&
      this.state.param &&
      this.state.param.name === 'path'
    ) {
      result = true
    }
    return result
  }

  paramIsAsync() {
    let result = false
    let eventNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, eventNodeId)
    let obj = getBlockObj({ block })
    let actionName = this.getName()
    if (
      block &&
      obj &&
      actionName &&
      ['setLog'].indexOf(actionName) >= 0 &&
      this.state.param &&
      this.state.param.name === 'topic'
    ) {
      result = 'serviceTopic'
    }
    return result
  }

  paramIsBlock(widgetName, actionName, paramName) {
    let result = false
    if (widgetName && actionName && paramName) {
      let widgets = widgetStore.widget
      if (
        widgets &&
        widgets[widgetName] &&
        widgets[widgetName].map &&
        widgets[widgetName].map.methodsMap &&
        widgets[widgetName].map.methodsMap[actionName] &&
        widgets[widgetName].map.methodsMap[actionName].params
      ) {
        let params = widgets[widgetName].map.methodsMap[actionName].params
        let param = params.find(param => param.name === paramName)
        if (param) {
          if (param.isBlock) {
            result = true
          }
        }
      }
    }
    return result
  }

  getOptionFonts(propsMap) {
    let options = []
    let optionLocales = {}
    let addedOptions = {}
    if (userStore.fontsList) {
      userStore.fontsList.forEach(fontItem => {
        let font = fontItem.font || fontItem.url
        if (!addedOptions[font]) {
          options.push(font)
          optionLocales[font] = {
            zh: fontItem.name,
            en: fontItem.name
          }
        }
        addedOptions[font] = true
      })
    }
    if (propsMap && propsMap.hasDefaultOptions) {
      // 添加默认
      options = options.concat(propsMap.options)
      optionLocales = Object.assign(optionLocales, propsMap.optionLocales)
    }
    return { options, optionLocales }
  }

  getOptionIcons(propsMap) {
    let options = []
    let optionLocales = {}
    let addedOptions = {}
    if (userStore.iconsList) {
      userStore.iconsList.forEach(fontItem => {
        if (!addedOptions[fontItem.url]) {
          options.push(fontItem.url)
          optionLocales[fontItem.url] = {
            zh: fontItem.name,
            en: fontItem.name
          }
        }
        addedOptions[fontItem.url] = true
      })
    }
    // 默认图标
    if (userStore.defaultIcons) {
      userStore.defaultIcons.forEach(fontItem => {
        options.push(fontItem.url)
        optionLocales[fontItem.url] = {
          zh: fontItem.name,
          en: fontItem.name
        }
      })
    }
    // 添加默认
    // options = options.concat(propsMap.options)
    // optionLocales = Object.assign(optionLocales, propsMap.optionLocales)
    return { options, optionLocales }
  }

  paramValueCom(propsMap) {
    let type = this.state.param.type
    let index = this.props.index
    let eventNodeId = this.props.eventNodeId || newEventStores.curEventNodeId
    let block = getEventBlockByBid(this.props.bid, eventNodeId)
    let obj = getBlockObj({ block })
    let node = getActionBlockObjNode({ obj, eventNodeId })
    let actionName = this.getName()
    // let _dbId = node ? getActionDbId({ node, bid: this.props.bid }) : undefined
    // let dbInfo = this.props.dbInfo
    // let dbId = dbInfo
    //   ? dbInfo.dbId
    //   : getActionDbId({ node, bid: this.props.bid })
    // let nodeType = dbInfo
    //   ? dbInfo.dbNodeType
    //   : getActionDbNodeType({ node, bid: this.props.bid })
    // let dbCols = dbInfo ? dbInfo.dbCols || [] : undefined
    // if (_dbId !== dbId) {
    //   dbId = undefined // 与当前action不符合的dbid不传入组件(避免覆盖问题)
    //   dbCols = undefined
    // }
    let com = undefined
    let paramName = this.state.param.name
    let value = this.state.value
    switch (type) {
      // 百分比也用formula处理
      case propType.Formula:
      case propType.FormulaColor:
        // 部分特殊参数注入公式的params
        let formulaParams = getSpecialParamFormulaParams({
          paramName,
          isNewEvent: true,
          objNode: node,
          actionName
        })
        let placeholder = this.getItemPlaceholder(propsMap)
        if (
          ['esInsert', 'esInsert_stage'].indexOf(actionName) >= 0 &&
          paramName === '_id'
        ) {
          placeholder = i18n.t(
            'EventView.jenga_action_block.insert_id_placeholder'
          )
        }
        let hasColorPicker = type === propType.FormulaColor
        let paramIsPath = this.paramIsPath()
        let paramIsAsync = this.paramIsAsync()
        let widgetName = node ? node.type : ''
        let paramIsBlock = this.paramIsBlock(widgetName, actionName, paramName)
        if (!paramIsBlock) {
          com = (
            <FormulaEditor
              className="action-formula-editor"
              bid={this.props.bid}
              uid={this.props.bid}
              paramName={paramName}
              hasColorPicker={hasColorPicker}
              value={value}
              placeholder={placeholder}
              params={formulaParams}
              isPath={paramIsPath}
              paramIsAsync={paramIsAsync}
              onChangeCode={this.onChangeValue.bind(this, index)}
              hasCons={consFormulaShow()}
            />
          )
        } else {
          com = (
            <EventJsonEditor
              height="200px"
              className="action-formula-editor"
              bid={this.props.bid}
              uid={this.props.bid}
              value={value}
              placeholder={placeholder}
              params={formulaParams}
              onChangeCode={this.onChangeValue.bind(this, index)}
              isBlock={paramIsBlock}
            />
          )
        }
        break
      case propType.FormulaJson:
        // 部分特殊参数注入公式的params
        let fEditorParams = getSpecialParamFormulaParams({
          paramName,
          isNewEvent: true,
          objNode: node,
          actionName
        })
        let jsonPlaceholder = this.getItemPlaceholder(propsMap)
        com = (
          <EventJsonEditor
            className="action-formula-editor"
            bid={this.props.bid}
            uid={this.props.bid}
            value={value}
            placeholder={jsonPlaceholder}
            params={fEditorParams}
            onChangeCode={this.onChangeValue.bind(this, index)}
          />
        )
        break
      case propType.Boolean:
        com = (
          <BlockActionBoolean
            className="action-block-action"
            type="boolean"
            bid={this.props.bid}
            uid={this.props.bid}
            value={value}
            noDefault={this.state.param.noDefault}
            onChange={this.onChangeValue.bind(this, index)}
          />
        )
        break
      // case propType.Select:
      // case propType.SelectUpload:
      // case propType.FontSelect:
      // case propType.IconSelect:
      //   let groups = propsMap && propsMap.optionGroup
      //   let options = propsMap && propsMap.options
      //   let optionsLocales = propsMap && propsMap.optionLocales
      //   if (propsMap && type === propType.FontSelect) {
      //     let temp = this.getOptionFonts(propsMap)
      //     options = temp.options
      //     optionsLocales = temp.optionLocales
      //   } else if (propsMap && type === propType.IconSelect) {
      //     let temp = this.getOptionIcons(propsMap)
      //     options = temp.options
      //     optionsLocales = temp.optionLocales
      //   }
      //   com = propsMap && (
      //     <BlockSelect
      //       className="action-block-select"
      //       type="select"
      //       value={value}
      //       isMultiple={!!propsMap.isMultiple}
      //       placeholder={propsMap.placeholder}
      //       optionsInfo={{
      //         optionsGroup: groups,
      //         options: options,
      //         optionLocales: optionsLocales
      //       }}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.MultiKeyValue:
      // case propType.MultiPureKeyValue:
      // case propType.MultiValue:
      //   com = (
      //     <BlockActionKeyValue
      //       className="action-key-value-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.KeyValueJson:
      //   let kvPlaceholder = this.getItemPlaceholder(propsMap)
      //   com = (
      //     <KeyValueJson
      //       keyValueClassName="action-key-value-group"
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       placeholder={kvPlaceholder}
      //       value={value}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.ArrColValue:
      // case propType.ArrMultiValue:
      //   let arrParams = getSpecialParamFormulaParams({
      //     paramName,
      //     isNewEvent: true,
      //     objNode: node,
      //     actionName
      //   })
      //   let affectArea = getParamsAffectArea({
      //     node,
      //     actionName
      //   })
      //   com = (
      //     <BlockActionColRowValue
      //       className="action-col-row-value-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       params={arrParams}
      //       paramsValid={affectArea}
      //       visible={this.props.visible}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.NormalCons:
      //   com = (
      //     <BlockActionNormalCons
      //       className="action-normal-cons-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.NormalUpdates:
      //   com = (
      //     <DbUpdateSelector
      //       value={value}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       type={'normal'}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.NormalOrders:
      //   com = (
      //     <BlockActionNormalOrders
      //       className="action-normal-orders-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbRange:
      //   com = (
      //     <BlockActionDbRange
      //       className="action-db-range-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbCons:
      //   com = (
      //     <DbConditionalSelector
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       isDbSearch={this.paramIsInDbSearch()}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbOrders:
      //   com = (
      //     <DbOrderSelector
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       isDbSearch={this.paramIsInDbSearch()}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbNumCol:
      //   com = (
      //     <DbNumColSelector
      //       value={value}
      //       dbId={dbId}
      //       dbCols={dbCols}
      //       nodeType={nodeType}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbUpdate:
      //   com = (
      //     <DbUpdateSelector
      //       value={value}
      //       dbId={dbId}
      //       dbCols={dbCols}
      //       nodeType={nodeType}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.ObjSelect:
      // case propType.ObjResult:
      // case propType.ObjSelectCb:
      //   let allowTypes = true
      //   let childOnly = false
      //   if (propsMap) {
      //     allowTypes =
      //       propsMap.allowTypes !== undefined ? propsMap.allowTypes : true
      //     childOnly =
      //       propsMap.childOnly !== undefined ? propsMap.childOnly : childOnly
      //   }
      //   com = (
      //     <BlockActionObjSelect
      //       className="action-obj-select-group"
      //       type={type}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       value={value}
      //       allowTypes={allowTypes}
      //       childOnly={childOnly}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.ObjJsonParamsSelect:
      //   com = (
      //     <BlockActionJsonParam
      //       bid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.ObjJsonMultiPaths:
      //   com = (
      //     <BlockActionJsonParamMult
      //       bid={this.props.bid}
      //       value={value}
      //       onChangeValue={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.JsonEditor:
      //   // 部分特殊参数注入公式的params
      //   let editorParams = getSpecialParamFormulaParams({
      //     paramName,
      //     isNewEvent: true,
      //     objNode: node,
      //     actionName
      //   })
      //   let jsonEditorPlaceholder = undefined
      //   if (this.state.param.isApiHeader || this.state.param.isApiBody) {
      //     let phOptions = {
      //       zh: "例如：{'name0':'value1','name1':'value2'}",
      //       en: "Ex: {'name0':'value1','name1':'value2'}"
      //     }
      //     jsonEditorPlaceholder = phOptions[i18n.language]
      //   } else {
      //     jsonEditorPlaceholder = this.getItemPlaceholder(propsMap)
      //   }
      //   com = (
      //     <div className="item-value" style={this.getWholeParamStyle()}>
      //       <EventJsonEditor
      //         className="action-formula-editor"
      //         bid={this.props.bid}
      //         uid={this.props.bid}
      //         value={value}
      //         params={editorParams}
      //         placeholder={jsonEditorPlaceholder}
      //         onChangeCode={this.onChangeValue.bind(this, index)}
      //       />
      //     </div>
      //   )
      //   break
      // case propType.CloneChild:
      //   let styles = {
      //     name: this.getParamNameStyle(),
      //     value: this.getParamValueStyle()
      //   }
      //   com = (
      //     <SubChildren
      //       cloneId={this.getCloneNodeId()}
      //       index={index}
      //       value={value}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       propStyles={styles}
      //     />
      //   )
      //   break
      // case propType.DbCols:
      //   let dbColsPlaceholder = this.getItemPlaceholder(propsMap)
      //   let params = getSpecialParamFormulaParams({
      //     paramName,
      //     isNewEvent: true,
      //     objNode: node,
      //     actionName
      //   })
      //   com = (
      //     <DbColsSelector
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       params={params}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       placeholder={dbColsPlaceholder}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbSearchRange:
      //   let searchRangePlaceholder = this.getItemPlaceholder(propsMap)
      //   let rangeParams = getSpecialParamFormulaParams({
      //     paramName,
      //     isNewEvent: true,
      //     objNode: node,
      //     actionName
      //   })
      //   com = (
      //     <DbSearchRange
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       params={rangeParams}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       placeholder={searchRangePlaceholder}
      //       isDbSearch={this.paramIsInDbSearch()}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbGroupByCols:
      //   com = (
      //     <DbGroupByCols
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DbGroupCols:
      // case propType.DbSelectCols:
      //   com = (
      //     <DbGroupCols
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DyQueryCons:
      //   let dyStyles = {
      //     name: this.getParamNameStyle(),
      //     value: this.getParamValueStyle()
      //   }
      //   let tips = propsMap && propsMap.desc && propsMap.desc[i18n.language]
      //   com = (
      //     <DyQueryCons
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       paramStyle={this.props.paramStyle}
      //       paramClass={this.props.paramClass}
      //       tips={tips}
      //       styles={dyStyles}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DyUpdate:
      //   com = (
      //     <DyUpdate
      //       value={value}
      //       dbId={dbId}
      //       dbCols={dbCols}
      //       nodeType={nodeType}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      // case propType.DyCons:
      //   com = (
      //     <DyCons
      //       value={value}
      //       dbId={dbId}
      //       nodeType={nodeType}
      //       dbCols={dbCols}
      //       bid={this.props.bid}
      //       uid={this.props.bid}
      //       onChange={this.onChangeValue.bind(this, index)}
      //     />
      //   )
      //   break
      default:
        // com = <div className="f--hlc">UNDEFINED-TODO</div>
        // 暂时默认用FormulaEditor
        let _formulaParams = getSpecialParamFormulaParams({
          paramName,
          isNewEvent: true,
          objNode: node,
          actionName
        })
        let _placeholder = this.getItemPlaceholder(propsMap)
        let _widgetName = node ? node.type : ''
        com = (
          <FormulaEditor
            className="action-formula-editor"
            bid={this.props.bid}
            uid={this.props.bid}
            paramName={paramName}
            value={value}
            placeholder={_placeholder}
            params={_formulaParams}
            onChangeCode={this.onChangeValue.bind(this, index)}
          />
        )
    }
    return com
  }

  getItemValueCom(propsMap) {
    return (
      <div className="item-value" style={this.getParamValueStyle()}>
        {this.paramValueCom(propsMap)}
      </div>
    )
  }

  getItemTips(propsMap) {
    if (!isHySa() && propsMap && propsMap.desc) {
      let tips = propsMap.desc[i18n.language]
      let eventView = document.querySelector('.event-view')
      return (
        <Tooltip
          title={tips}
          arrowPointAtCenter={true}
          placement="right"
          overlayClassName="param-tips-tooltip"
          getPopupContainer={() => eventView}
        >
          <span
            className="param-tips"
            dangerouslySetInnerHTML={{ __html: iconStrObj.help }}
          />
        </Tooltip>
      )
    }
    return null
  }

  getItemPlaceholder(propsMap) {
    let placeholder = undefined
    if (propsMap && propsMap.placeholder) {
      placeholder =
        typeof propsMap.placeholder === 'string'
          ? propsMap.placeholder
          : propsMap.placeholder[i18n.language]
    }
    return placeholder
  }

  render() {
    let propsMap = this.getParamPropsMap()
    // 处理小模块中的文本变量公共数据,当类型为select时需另外获取propsMap
    if (
      this.state.param.type === 'Select' &&
      this.state.param.mini &&
      !propsMap
    ) {
      let nodeId = this.eventNodeId || newEventStores.curEventNodeId
      let block = getEventBlockByBid(this.props.bid, nodeId)
      let obj = getBlockObj({ block })
      if (block && obj) {
        let node = getActionBlockObjNode({
          obj,
          nodeId
        })
        if (node && node.props && node.props.classId) {
          let classId = node.props.classId
          const nodeInfo = getNodeFromMap({
            nodeId: this.state.param.name.split('_')[1],
            caseId: treeStores.curCaseId,
            classId
          })
          if (nodeInfo) {
            propsMap = {
              options: nodeInfo.props.options.split(',')
            }
          }
        }
      }
    }
    // method的param的map的hideKeep控制参数显隐,运行时该参数仍会传入方法中
    // 在需要改动方法参数的需求中，可在需要隐藏的param加上hideKeep:true,
    // 则参数不会显示在编辑界面中，运行时候仍会传入方法中,保持新旧项目中同一方法参数和表现一致
    if (propsMap && propsMap.hideKeep) {
      return null
    }
    // 在group内隐藏
    // if (this.state.param && this.state.param.pGroupHide) {
    //   return null
    // }
    return this.state.param &&
      [propType.CloneChild, propType.JsonEditor, propType.DyQueryCons].indexOf(
        this.state.param.type
      ) >= 0 ? (
      this.paramValueCom()
    ) : this.state.param.type !== propType.Hidden ? (
      <div
        className={cls('param-item f--h', this.props.paramClass)}
        style={this.props.paramStyle}
      >
        <div
          className="item-name f--hlc"
          title={this.getParamName()}
          style={this.getParamNameStyle()}
        >
          {this.getParamName()}
          {this.getItemTips(propsMap)}
        </div>
        <div className="item-equal">=</div>
        {this.getItemValueCom(propsMap)}
      </div>
    ) : null
  }
}
