// 核心库
import React, { Component } from 'react'
import { connect } from 'dva'
// 组件库
import { Form, Button } from 'antd'
// 工具库
import { isEqual } from 'lodash'
import storage from '../utils/storage'
import { guid } from '../utils/common'
class LocalSearch extends Component {
  constructor (props) {
    super(props)
    this.shareKey = props.shareKey // 共享数据标识
    this.isRemember = props.isRemember // 是否记忆搜索条件
    this.insRef = guid() // 当前 Search 组件的唯一标识
  }

  componentDidMount () {
    this.checkShareData().then(() => {
      !this.props.preventDefaultSearch && this.handleSearch()
    })
  }

  componentDidUpdate () {
    const targetDom = document.getElementById(this.insRef)
    if (targetDom) {
      const computedStyle = window.getComputedStyle(targetDom)
      const { width, height, marginTop, marginBottom, marginLeft, marginRight } = computedStyle
      this.props.onSize instanceof Function && this.props.onSize({
        width: parseInt(width),
        height: parseInt(height),
        fullWidth: parseInt(marginLeft) + parseInt(width) + parseInt(marginRight),
        fullHeight: parseInt(marginTop) + parseInt(height) + parseInt(marginBottom)
      })
    }
  }

  componentWillUnmount () {
    // 组件销毁时清空当前共享信息
    if (this.shareKey) {
      this.props.dispatch({
        type: 'search/cleanShareIns',
        payload: {
          key: this.shareKey,
          insRef: this.insRef
        }
      })
    }
    // 如果不记住查询条件，则组件销毁时，清空共享数据
    if (this.shareKey && !this.isRemember) {
      this.props.dispatch({
        type: 'search/setShareData',
        payload: {
          key: this.shareKey,
          data: null // 此处与 AdvanceSearch 不同，置为 null
        }
      })
      storage('session').removeItem(this.shareKey)
    }
  }

  // 相同 shareKey 的搜索组件共享搜索条件
  setShareIns = (self = true) => {
    const { search, dispatch } = this.props
    let stopSelfSearch = false
    if (this.shareKey) {
      const instances = search.shareIns[this.shareKey] || []
      const targetIns = instances.filter(ins => ins.insRef !== this.insRef)
      if (targetIns.length) {
        if (self) {
          // 设置自身状态
          const { instance } = targetIns[0]
          const { getExtraData: insGetExtraData } = instance.props || {}
          const { setExtraData: thisSetExtraData, getExtraData: thisGetExtraData } = this.props
          if (insGetExtraData instanceof Function && thisSetExtraData instanceof Function && thisGetExtraData instanceof Function) {
            const insExtraData = insGetExtraData()
            const thisExtraData = thisGetExtraData()
            if (!isEqual(insExtraData, thisExtraData)) {
              stopSelfSearch = true
              thisSetExtraData(insExtraData, this.handleSearch)
            }
          }
        } else {
          // 设置其他关联的Search组件状态
          targetIns.forEach(({ instance }) => {
            const { setExtraData: insSetExtraData, getExtraData: insGetExtraData } = instance.props || {}
            const { getExtraData: thisGetExtraData } = this.props
            if (thisGetExtraData instanceof Function && insSetExtraData instanceof Function && insGetExtraData instanceof Function) {
              const thisExtraData = thisGetExtraData()
              const insExtraData = insGetExtraData()
              if (!isEqual(thisExtraData, insExtraData)) {
                // 此处不设置stopSelfSearch标志为true，因为本身也要进行搜索
                insSetExtraData(thisExtraData, instance.handleSearch)
              }
            }
          })
        }
      }
      // 存储当前 Search 组件实例
      dispatch({
        type: 'search/setShareIns',
        payload: {
          key: this.shareKey,
          insRef: this.insRef,
          instance: this
        }
      })
    }
    return stopSelfSearch
  }

  // 存储当前 shareKey 的查询数据
  setShareData = () => {
    const { getExtraData } = this.props
    if (this.shareKey && getExtraData instanceof Function) {
      const data = getExtraData()
      this.props.dispatch({
        type: 'search/setShareData',
        payload: {
          key: this.shareKey,
          data
        }
      })
      storage('session').setItem(this.shareKey, data)
    }
  }

  // 提取本地存储的共享查询条件作为预设值
  checkShareData = () => {
    /**
     * 为什么使用 Promise，因为这里需要确保在父组件 didMount 之后（也就是所有子组件都 didMount 完成之后）调用，
     * 避免父组件的多个子组件都有对父组件进行 setState 操作时，state 不按预期赋值
     */
    return Promise.resolve().then(() => {
      const { setExtraData: thisSetExtraData, getExtraData: thisGetExtraData, search } = this.props
      if (this.shareKey && thisSetExtraData instanceof Function && thisGetExtraData instanceof Function) {
        const localExtraData = search.shareData[this.shareKey] || storage('session').getItem(this.shareKey).val
        if (localExtraData && !isEqual(localExtraData, thisGetExtraData())) {
          thisSetExtraData(localExtraData)
        }
      }
    })
  }

  // 执行搜索 提供给 ref 调用
  handleSearch = (self = true) => {
    if (this.setShareIns(self)) return
    /**
     * setShareIns 之后调用，是因为在 setShareIns 中 extraData 是 setState 之后才会被赋值上最新值，
     * 所以需要在 setState 之后，再获取到 extraData 并存储
     */
    this.setShareData()

    const { currActivatedMenu } = this.props.app || {}
    const rule = {
      rules: [],
      groups: [],
      orgType: 0,
      menuParameter: currActivatedMenu && currActivatedMenu.MENU_FORM_PARAMS ? currActivatedMenu.MENU_FORM_PARAMS : ''
    }

    const { onSearch } = this.props
    onSearch instanceof Function && onSearch(rule)
    return rule
  }

  render () {
    const { extraSearch, iconEle } = this.props
    return (
      <Form
        id={this.insRef}
        hideRequiredMark
        className='opt-search opt-search__form'
      >
        {extraSearch || this.props.children}
        <div className='opt-search__btns-zone'>
          <Button type='primary' onClick={() => this.handleSearch(false)}>查询</Button>
          <div className='opt-search__tool-wrap'>
            <div className='opt-search__children'>{iconEle}</div>
          </div>
        </div>
      </Form>
    )
  }
}

export default connect(({ app, search }) => ({ app, search }))(LocalSearch)
