import React from 'react'
import { connect } from 'dva'
import { Row, Col, Form, message, Input, Select, InputNumber } from 'antd'
import { extendRule, initFilter, empty, getPropertyData, extendInclude, getDataFieldValue, setDataFieldValue } from '../../utils/common'
import styles from './edit.css'
import moment from 'moment'
import EditComponent from "../../baseComponents/EditComponent"

const FormItem = Form.Item
const Option = Select.Option

class EditCell extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      operator: 1,
      presetOption: { label: '修改为', value: 1 }
    }
  }

  componentDidUpdate () {
    const { operator } = this.state
    const { operator: colOperator } = this.props.colConfig
    if (operator !== colOperator) {
      this.props.colConfig.operator = operator
    }
  }

  getSelectOperate = (colConfig) => {
    const { batchColumnConfig } = this.props

    const options = [this.state.presetOption]
    if (batchColumnConfig) {
      const temps = batchColumnConfig[colConfig.controlType]
      if (temps && temps.operators && temps.operators.length) {
        temps.operators.forEach(t => {
          options.push(t)
        })
      }
    }

    if (!colConfig.isRequire) {
      options.push({ label: '清空', value: 2 })
    }

    const { operator } = this.state
    return (
      <Select value={operator} onChange={val => { this.setState({ operator: val }) }}>
        {
          options.map(t => {
            return <Option value={t.value} key={t.value}>{t.label}</Option>
          })
        }
      </Select>
    )
  }

  getSelectValueRender = (colConfig) => {
    const { record, batchColumnConfig, setHeadColumnConfig, getControl } = this.props

    let operatorParam = null
    const { operator } = this.state
    if (operator === null || operator === undefined) return null

    if (batchColumnConfig) {
      const temps = batchColumnConfig[colConfig.controlType]
      if (temps) {
        operatorParam = temps[operator]
      }
    }

    if (operatorParam && operatorParam.render) {
      return operatorParam.render(colConfig)
    }

    if (operator === 2) {
      return <span>清空</span>
    }

    setHeadColumnConfig({ colConfig, record })
    return getControl(colConfig)
  }

  render () {
    const { colConfig } = this.props
    return (
      <Row gutter={12}>
        <Col span={8}>{this.getSelectOperate(colConfig)}</Col>
        <Col span={16}>{this.getSelectValueRender(colConfig)}</Col>
      </Row>
    )
  }
}

class BatchEdit extends EditComponent {
  componentWillReceiveProps (NextProps) {
    super.componentWillReceiveProps(NextProps)
    const reloadKey = NextProps.data?.reloadKey || null
    const reload = reloadKey ? NextProps.editPage[reloadKey] : false
    if (NextProps.id !== this.props.id || this.props.isAdd !== NextProps.isAdd || reload) {
      this.props.form.resetFields()
      this.onLoadData()
      if (reload) {
        this.props.dispatch({
          type: 'editPage/save',
          payload: {
            [reloadKey]: false,
          },
        })
      }
    }
  }

  getColumnByColumnConfig = () => {
    const getDateConfig = (isAdd, type) => {
      return {
        render: (colConfig) => {
          return (
            <InputNumber
              value={getDataFieldValue(this.state.data, colConfig.field + '_other')}
              min={0}
              onChange={(e) => {
                if (e === null || e === undefined) return
                this.saveHeadRecord({
                  [colConfig.field + '_other']: e.target && e.target.value ? e.target.value : (typeof e === 'object' ? null : e)
                })
              }}
            />
          )
        },
        getValue: (colConfig, value) => {
          if (value) {
            const otherValue = this.getFieldValue(colConfig.field + '_other')
            if (otherValue) {
              if (isAdd) {
                return moment(value).add(otherValue, type).format('YYYY-MM-DD HH:mm:ss')
              } else {
                return moment(value).subtract(otherValue, type).format('YYYY-MM-DD HH:mm:ss')
              }
            }
          }
          return value
        },
      }
    }

    const batchColumnConfig = {
      1: {
        operators: [
          { value: 11, label: '在开始添加' },
          { value: 12, label: '在结束添加' },
          { value: 13, label: '替换' },
        ],
        11: {
          getValue: (colConfig, value) => {
            if (value) {
              const srcValue = this.getFieldValue(colConfig.field)
              if (srcValue) {
                return srcValue + value
              }
            }
            return value
          },
        },
        12: {
          getValue: (colConfig, value) => {
            if (value) {
              const srcValue = this.getFieldValue(colConfig.field)
              if (srcValue) {
                return value + srcValue
              }
            }
            return value
          },
        },
        13: {
          render: (colConfig) => {
            return (
              <>
                {this.getControl(colConfig)}
                <Input value={getDataFieldValue(this.state.data, colConfig.field + '_other')} onChange={(e) => {
                  let tmpValue = (e.target && e.target.value ? e.target.value : (typeof e === 'object' ? null : e))
                  this.saveHeadRecord({
                    [colConfig.field + '_other']: tmpValue
                  })
                }} />
              </>
            )
          },
          getValue: (colConfig, value) => {
            if (value) {
              const srcValue = this.getFieldValue(colConfig.field)
              if (srcValue) {
                const replaceValue = this.getFieldValue(colConfig.field + '_other')
                return value.toString().replace(new RegExp(srcValue, 'g'), replaceValue)
              }
            }
            return value
          },
        }
      },
      2: {
        operators: [
          { value: 21, label: '增加天数' },
          { value: 22, label: '增加月数' },
          { value: 23, label: '增加年数' },
          { value: 24, label: '减少天数' },
          { value: 25, label: '减少月数' },
          { value: 26, label: '减少年数' },
        ],
        21: {
          ...getDateConfig(true, 'd'),
        },
        22: {
          ...getDateConfig(true, 'M'),
        },
        23: {
          ...getDateConfig(true, 'y'),
        },
        24: {
          ...getDateConfig(false, 'd'),
        },
        25: {
          ...getDateConfig(false, 'M'),
        },
        26: {
          ...getDateConfig(false, 'd'),
        }
      }
    }

    this.setState({
      batchColumnConfig
    })
  }

  onGetEntityData (allColumns, navFields) {
    this.getColumnByColumnConfig()

    const editConfig = this.getEditConfig()
    if (!editConfig || !editConfig.batchGetApi) return

    const { data, login, dispatch } = this.props
    if (data && typeof data.getIds === 'function') {
      const ids = data.getIds()
      if (!ids) return

      const json = initFilter(login.OrgId)
      json.FilterGroup.IsAnd = false

      const idsArr = ids.split(',')
      idsArr.forEach(item => {
        extendRule(json, 'ID', 1, item)
      })
      navFields.forEach(item => {
        extendInclude(json, item)
      })

      dispatch({
        type: 'app/getDataByPost',
        payload: json,
        url: editConfig.batchGetApi,
        onlyData: false,
        onComplete: (ret) => {
          if (ret && ret.IsSuccessful) {
            this.setState({
              batchData: ret.Data || [],
              data: {}
            })
          } else {
            message.error(ret.ErrorMessage)
          }
        }
      })
    }
  }

  initColumnConfigByEditCols (params) {
    params.isBatchEdit = true
    params.editPanels = null
    super.initColumnConfigByEditCols(params)
  }

  onSave (closeType, clearType) {
    const { data, batchData, batchColumnConfig } = this.state
    if (!batchData || !batchData.length) return

    const headColumnConfig = this.getEditConfig() || {}
    const columns = headColumnConfig.columns || []
    const dataKeys = Object.keys(data)
    const validCols = columns.filter(item => dataKeys.indexOf(item.field) !== -1)

    const { dispatch, onSave, formCode } = this.props
    this.props.form.validateFieldsAndScroll(errors => {
      if (errors) return

      //修改值
      let updatedCount = 0
      batchData.forEach(item => {
        let emptyCount = 0
        validCols.forEach(col => {
          const emptyVal = empty(getDataFieldValue(data, col.field), true)
          if (emptyVal) {
            emptyCount++
            return
          }

          // 直接修改值
          if (!col.operator || col.operator === 1) {
            const newVal = getDataFieldValue(data, col.field)
            if (newVal) {
              setDataFieldValue(item, col.field, newVal)
              if (col.controlType === 9) {
                const idField = col.data?.idField || null
                const idVal = getDataFieldValue(data, idField)
                if (idVal) {
                  setDataFieldValue(item, idField, idVal)
                } else {
                  const configData = col.data
                  this.fillDropDownSelectRecord({
                    record: this.state.data,
                    data: item,
                    saveField: configData.saveField,
                    labelField: configData.labelField,
                    navField: configData.navField,
                    field: col.field,
                    idField: col.idField
                  })
                }
              }
            }
          }
          // 清空
          else if (col.operator === 2) {
            const enumName = col.data?.enumName || null
            if (col.controlType === 3 || col.controlType === 7) {
              setDataFieldValue(item, col.field, 0)
            } else if (col.controlType === 4 || col.controlType === 5 && !enumName) {
              setDataFieldValue(item, col.field, false)
            } else if (col.controlType === 9) {
              const idField = col.data?.idField || null
              idField && setDataFieldValue(item, idField, null)
            } else {
              setDataFieldValue(item, col.field, null)
            }
          }
          else {
            if (batchColumnConfig) {
              const temps = batchColumnConfig[col.controlType]
              if (temps) {
                const operatorParam = temps[col.operator]
                if (operatorParam && operatorParam.getValue) {
                  const value = operatorParam.getValue(col, getDataFieldValue(item, col.field))
                  setDataFieldValue(item, col.field, value)
                }
              }
            }
          }
        })
        emptyCount === validCols.length && (updatedCount++)
      })

      if (updatedCount === batchData.length) {
        message.info('未检测到变更')
        return
      }

      //批量保存
      this.setState({ btnLoading: true })
      const editConfig = this.getEditConfig()
      const payload = batchData.map(item => getPropertyData(item))
      dispatch({
        type: 'app/getDataByPost',
        payload: { Data: payload },
        url: editConfig.batchSaveApi,
        onComplete: (ret) => {
          if (ret) {
            message.success('执行成功')
            this.addEditLog({
              formCode,
              ids: payload.map(item => item.ID).join(','),
              codes: payload.map(item => item.CODE).join(','),
              extData: JSON.stringify(payload)
            })
          }
          this.setState({ btnLoading: false })
          if (typeof onSave === 'function') {
            onSave(this.state.data)
          }
          this.onLoadData()
          this.props.onCancel instanceof Function && this.props.onCancel()
        }
      })
    })
  }

  render () {
    const headColumnConfig = this.getEditConfig() || {}
    const columns = headColumnConfig.columns || []
    const { data, batchColumnConfig } = this.state
    return (
      <Form labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
        <Row gutter={12}>
          {
            columns && columns.length
              ? columns.map((item, index) => {
                if (!item.field) return null
                return (
                  <Col key={`${item.ID}_${index}`} span={12}>
                    <FormItem label={item.label}>
                      <EditCell
                        colConfig={item}
                        record={data}
                        batchColumnConfig={batchColumnConfig}
                        setHeadColumnConfig={(payload) => this.setHeadColumnConfig(payload)}
                        getControl={(payload) => this.getControl(payload)}
                      />
                    </FormItem>
                  </Col>
                )
              })
              : null
          }
        </Row>
        <div className={styles.saveBtn}>{this.getRenderBtns({ btns: headColumnConfig.btns })}</div>
      </Form>
    )
  }
}

// getControl 需要用到 this.props.app
export default connect(({ login, app, editPage }) => ({ login, app, editPage }))(Form.create()(BatchEdit))
