import React from 'react'
import { connect } from 'dva/index'
import { Input, Icon, AutoComplete, Pagination, Spin } from 'antd'
import FromModal from '../FormModal'
import {
  extendFilterGroup,
  extendGroupRule,
  extendInclude,
  extendOrder,
  extendRule,
  getDataFieldValue,
  initFilter,
  initFilterGroup,
  validUUID
} from '../../utils/common'
import { isEqual } from 'lodash'
import moment from 'moment'

const AutoOption = AutoComplete.Option

class DropDownPagination extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      data: {
        Data: []
      },
      value: '',
      oldValue: '',
      localFirst: false // 初次加载时，是否以本地记忆的查询条件优先
    }
    this.handleAutoCompleteKeyDown = this.handleAutoCompleteKeyDown.bind(this)
  }

  componentDidMount() {
    const { value, data, colConfig, record } = this.props
    this.setState({
      value: value,
      oldValue: value,
      isUpdateValue: false,
      localFirst: value && value !== data.dataValue
    }, () => {
      if (record?.ID && !record?.CREATE_TIME && colConfig?.column?.DEFAULT_VALUE) {
        this.checkAutoComplete({ target: { value: colConfig.column.DEFAULT_VALUE } })
      }
      //(value || data.dataValue) && this.checkAutoComplete({ target: { value: value || data.dataValue } })
    })
  }

  UNSAFE_componentWillReceiveProps(NextProps) {
    const { value } = NextProps
    if (this.state.oldValue !== value || this.state.isUpdateValue) {
      this.setState({
        value: value,
        oldValue: value,
        isUpdateValue: false
      })
    }
  }

  componentDidUpdate(prevProps, prevState) {
    if (!isEqual(prevState.data, this.state.data)) {
      const { data, onLoadData } = this.props
      onLoadData instanceof Function && onLoadData(data.id, this.state.data && this.state.data.Data ? this.state.data.Data : [])
    }
  }

  handleFetchAutoFilterEvent = (params) => {
    const { data, record } = this.props
    const { onFilter } = data || {}
    if (typeof onFilter === 'function') {
      onFilter({
        record,
        params: params,
        colConfig: this.props.colConfig,
        thisRef: this.props.thisRef
      })
    }
  }

  getAutoCompleteLoadParam = (params = {}, e) => {
    const { data } = this.props
    const { filterField, sortField, showField, sortOrder, navField, extIncludeFields } = data || {}
    const sortName = this.state.localFirst ? [validUUID(e?.target?.value) ? 'ID' : 'NAME'] : filterField ? filterField.split(',') : ['NAME', 'CODE']
    const initParams = initFilter(this.props.login.OrgId, '', sortName[0], 0)
    const sortFields = sortField ? sortField.split(',') : []
    const sortOrders = sortOrder ? sortOrder.split(',') : []
    const arrShowField = showField ? showField.split(',') : ['CODE', 'NAME']

    if (e) {
      if (e.target.value) {
        const group = initFilterGroup(false)
        let filterArray = filterField ? filterField.split(',') : ['NAME'];
        filterArray.forEach((i, n) => {
          extendGroupRule(group, i, i === 'ID' ? 1 : 9, e.target.value)
        })
        extendFilterGroup(initParams, group)
      }
      this.setState({
        autoChangeValue: e.target.value
      })
    }
    const loadParam = { ...initParams, ...params }
    // 添加自定义排序
    if (sortFields && sortOrders && sortFields.length && sortOrders.length) {
      loadParam['Sort'] = ''
      sortFields.forEach((n, i) => {
        extendOrder(loadParam, n, sortOrders[i])
      })
    }
    const navFields = []
    // 添加导航属性
    const tmpNavFields = navField ? navField.split(',') : ['ID']
    if (tmpNavFields && tmpNavFields.length > 0) {
      tmpNavFields.forEach(t => {
        if (t && t.indexOf('.') > 0) {
          const pos = t.lastIndexOf('.')
          const includeField = t.substring(0, pos)
          navFields.push(includeField)
        }
      })
    }
    if (arrShowField && arrShowField.length > 0) {
      arrShowField.forEach(t => {
        if (t && t.indexOf('.') > 0) {
          const pos = t.lastIndexOf('.')
          const includeField = t.substring(0, pos)
          navFields.push(includeField)
        }
      })
    }
    // 填充导航属性
    if (extIncludeFields) {
      extIncludeFields.forEach(t => {
        navFields.push(t)
      })
    }

    // 去重添加
    if (navFields.length) {
      const tmp = [...new Set(navFields)]
      tmp.forEach((n, i) => {
        extendInclude(loadParam, n)
      })
    }
    return loadParam
  }

  fetchAutoComData = (params = {}, e) => { // 获取autocomplete数据
    const { api, data } = this.props
    if (!api) return Promise.reject(new Error('can not find api'))
    const loadParam = this.getAutoCompleteLoadParam(params, e)
    this.handleFetchAutoFilterEvent(loadParam)
    this.setState({
      loadParam
    })
    if (data && data.filterOrgType) {
      loadParam.OrgType = data.filterOrgType
    }
    if (data && data.authOrgCodes) {
      loadParam.AuthOrgCodes = data.authOrgCodes
    }
    return this.props.dispatch({
      type: 'app/getDataByPost',
      payload: loadParam,
      url: api,
      onlyData: false,
      isIgnoreTenant: data.isIgnoreTenant
    }).then(res => { this.setState({ data: res }) })
  }

  autoComDataPage = (num) => {
    const { data } = this.props
    const { filterField } = data || {}
    const arrOBj = filterField ? filterField.split(',') : ['NAME', 'CODE']
    const sortName = filterField ? filterField.split(',') : ['NAME', 'CODE']
    const params = initFilter(this.props.login.OrgId, '', sortName[0], 0, num)
    if (this.state.autoChangeValue) {
      const group = initFilterGroup(false)
      arrOBj.forEach((i, n) => {
        extendGroupRule(group, i, 9, this.state.autoChangeValue)
      })
      extendFilterGroup(params, group)
    }
    this.fetchAutoComData(params)
  }

  handleFieldChangeEvent = (value) => {
    const { data } = this.props
    const { onChange } = data || {}
    if (typeof onChange === 'function') {
      onChange({
        value,
        colConfig: this.props.colConfig,
        thisRef: this.props.thisRef
      })
    }
    this.setState({
      value: value
    })
    if (!value) {
      this.selectAutoItem(null)
    }
    else {
      if (!this.isSelectItem) {
        if (value.toString().indexOf('-') === -1) {
          this.isCheckAutoComplete = true
        }
      }
    }
  }

  handleChangeAuto = (value, callback) => {
    if (this.isSelectItem || validUUID(value)) return

    const { data } = this.props
    const { filterField, onChangeHandle } = data || {}
    const arrOBj = filterField ? filterField.split(',') : ['NAME', 'CODE']
    const sortName = filterField ? filterField.split(',') : ['NAME', 'CODE']
    const params = initFilter(this.props.login.OrgId, '', sortName[0], 0)
    if (value) {
      const group = initFilterGroup(false)
      arrOBj.forEach((i, n) => {
        extendGroupRule(group, i, 9, value)
      })
      extendFilterGroup(params, group)
    }
    const nowT = moment().format('x')
    if (!this.autoCompleteChangeT || nowT - this.autoCompleteChangeT > 200) {
      this.fetchAutoComData(params).then(() => { callback instanceof Function && callback() })
    }
    this.setState({
      autoChangeValue: value
    })
    this.autoCompleteChangeT = moment().format('x')
    this.handleFieldChangeEvent(value)
    if (onChangeHandle && typeof onChangeHandle === 'function') {
      onChangeHandle(value)
    }
  }

  handleAutoCompleteKeyDown(event) {
    if (event.keyCode === 13) {
      const nowT = moment().format('x')
      if (nowT - this.autoCompleteChangeT < 1000) {
        this.isCheckAutoComplete = true
        this.checkAutoComplete()
      }
    }
  }

  checkAutoComplete = (autoLoadParam) => {
    if (this.isCheckAutoComplete || autoLoadParam) {
      const { dispatch, data, api } = this.props
      let { labelField } = data || {}
      const that = this
      const loadParam = this.getAutoCompleteLoadParam({}, autoLoadParam)
      if (!labelField) {
        labelField = 'NAME';
      }
      !autoLoadParam && extendRule(loadParam, labelField, 1, this.state.autoChangeValue)
      dispatch({
        type: 'editPage/getAutoCompleteData',
        payload: loadParam,
        url: api,
        isIgnoreTenant: data.isIgnoreTenant,
        onComplete: function (ret) {
          that.setState({
            data: ret,
            localFirst: false
          }, () => {
            if (ret && ret.Data && ret.Data.length === 1) {
              that.selectAutoItem(ret.Data[0].ID, null, undefined, undefined, autoLoadParam)
            } else {
              that.selectAutoItem(null, null, true, that.state.autoChangeValue, autoLoadParam)
            }
          })
        }
      })
    }
  }

  selectAutoItem = (value, option, isClear, val, autoLoadParam) => {
    const { data, onSelect, onSearchRef } = this.props
    const { navField, isKeepValueByClear, labelField } = data || {}
    this.isSelectItem = true
    this.isCheckAutoComplete = false
    if (typeof onSelect === 'function') {
      if (value) {
        // document.onfocus()
        if (this.state.data && this.state.data.Data) {
          const navFields = navField ? navField.split(',') : ['ID']
          this.state.data.Data.forEach(t => {
            if (value === t.ID) {
              const saveValues = []
              for (let j = 0; j < navFields.length; j++) {
                saveValues.push(getDataFieldValue(t, navFields[j]))
              }
              onSelect({
                data: saveValues,
                record: t,
                complete: () => {
                  this.isSelectItem = false
                  autoLoadParam && onSearchRef instanceof Function && onSearchRef()
                },
                colConfig: this.props.colConfig,
                thisRef: this.props.thisRef
              })
            }
          })
        }
      }
      else if (isClear && isKeepValueByClear) {
        const saveValues = []
        const navFields = navField ? navField.split(',') : ['ID']
        const t = {
          [labelField || 'NAME']: val
        }
        for (let j = 0; j < navFields.length; j++) {
          saveValues.push(getDataFieldValue(t, navFields[j]))
        }
        onSelect({
          data: saveValues,
          record: t,
          complete: () => {
            this.isSelectItem = false
            autoLoadParam && onSearchRef instanceof Function && onSearchRef()
          },
          colConfig: this.props.colConfig,
          thisRef: this.props.thisRef
        })
      }
      else {
        onSelect({
          data: [],
          record: null,
          isClear: true,
          complete: () => {
            this.isSelectItem = false
            autoLoadParam && onSearchRef instanceof Function && onSearchRef()
          },
          colConfig: this.props.colConfig,
          thisRef: this.props.thisRef
        })
        this.setState({
          isUpdateValue: true
        })
      }
    }
  }

  handleEditFormSave = (val) => {
    const { editFormFilter, editFormFilterValue } = this.props
    if (editFormFilter && editFormFilterValue) return // 存在子表的，行为可能不是新增，所以不坐操作
    this.handleChangeAuto(val.NAME, () => this.selectAutoItem(val.ID))
  }

  render() {
    const { data, disabled, loading, showFormCode, showFormId, editFormCode, editFormFilter, editFormFilterValue, placeholder, onBlur, style } = this.props
    const { showField, labelField, width } = data || {}
    const autoLoading = loading.effects['app/getDataByPost']
    const arrShowField = showField ? showField.split(',') : ['CODE', 'NAME']
    let autoComData = this.state.data
    if (!autoComData) {
      autoComData = {
        TotalCount: 0
      }
    }
    if (!autoComData.Data) {
      autoComData.Data = []
    }
    const isShowSrcBtn = showFormCode && showFormId
    const options = autoComData.Data.map(opt => {
      const nodearr = arrShowField.map((i, key) => {
        if (key < arrShowField.length && key > 0) {
          const v1 = getDataFieldValue(opt, i)
          return '-' + (v1 == null ? '空' : v1)
        } else {
          const v1 = getDataFieldValue(opt, i)
          return (v1 == null ? '空' : v1)
        }
      })
      return (
        <AutoOption key={opt.ID} label={opt[(labelField || 'NAME')]} value={opt['ID'] || ''}>
          {nodearr}
        </AutoOption>
      )
    }).concat([
      <AutoOption disabled key='pagination' className='show-all'>
        <Spin spinning={autoLoading}>
          <Pagination
            current={this.state.loadParam ? this.state.loadParam.PageIndex : 0}
            onChange={(num) => this.autoComDataPage(num)}
            size='small'
            total={autoComData.TotalCount}
          />
        </Spin>
      </AutoOption>
    ])

    const value = this.state.value
    return (
      <div id='advanceSearch'>
        <AutoComplete
          className='certain-category-search'
          dropdownClassName='certain-category-search-dropdown'
          dropdownMatchSelectWidth={false}
          dropdownStyle={{ width: 300 }}
          style={isShowSrcBtn || editFormCode ? { width: '80%' } : { width: '100%' }}
          dataSource={options}
          allowClear
          onChange={(e) => this.handleChangeAuto(e)}
          placeholder=''
          optionLabelProp='label'
          onSelect={(value, option) => {
            const nowT = moment().format('x')
            if (!this.autoCompleteChangeT || nowT - this.autoCompleteChangeT > 1000) {
              this.selectAutoItem(value, option)
            }
          }}
          disabled={disabled}
          value={value}
        >
          <Input
            disabled={disabled}
            onClick={(e) => this.fetchAutoComData({}, e)}
            onBlur={() => {
              onBlur instanceof Function && onBlur()
              this.checkAutoComplete()
            }}
            onKeyDown={(e) => { this.handleAutoCompleteKeyDown(e) }}
            placeholder={placeholder}
            style={{ ...style, width: width }}
          />
        </AutoComplete>
        {
          isShowSrcBtn ? <FromModal formCode={showFormCode} data={{ id: showFormId, isShow: true }}>
            <Icon type='info-circle' style={{ marginLeft: 8, fontSize: 20 }} />
          </FromModal> : null
        }
        {
          editFormCode ? <FromModal formCode={editFormCode} data={{ editFormFilter, editFormFilterValue, onSave: this.handleEditFormSave }} destroyOnClose>
            <Icon type='plus-square' style={{ marginLeft: 8, fontSize: 20 }} />
          </FromModal> : null
        }
      </div>
    )
  }
}

export default connect(({ app, loading, listPage, login }) => ({ app, loading, listPage, login }))(DropDownPagination)
