import React from 'react'
import cls from 'classnames'
import citeActions from 'actions/cite'
import citeStores from 'stores/cite'
import newEventStores from 'stores/newEvent'
import { getEventNodeById } from 'stores/funcs/newEvent'
import { shouldCite } from 'stores/funcs/cite'
import { shallowEqualImmutable } from 'utils/utils'

export default class BlockCite extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      curEventNodeId: newEventStores.curEventNodeId,
      isActive: false, // 是否处于引用激活态
      memoExpanded: newEventStores.showMemo // 备注是否展开
    }

    this.onEventChange = this.onEventChange.bind(this)
    this.onCiteChange = this.onCiteChange.bind(this)
    this.getIsActive = this.getIsActive.bind(this)
    this.hasBlockCite = this.hasBlockCite.bind(this)
    this.onToggleBlockCite = this.onToggleBlockCite.bind(this)
  }

  componentDidMount() {
    this.unsubscribe = newEventStores.listen(this.onEventChange)
    this.unsubscribeCite = citeStores.listen(this.onCiteChange)
  }

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

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

  componentDidUpdate(preProps) {
    let isActive = this.getIsActive()
    if (this.state.isActive !== isActive) {
      this.setState({
        isActive: isActive
      })
    }
  }

  onEventChange(status) {
    let obj = {}
    if (status && status.types) {
      if (status.types.includes('curEventNodeId')) {
        obj.curEventNodeId = status.data.curEventNodeId
      }
      if (status.types.includes('showMemo')) {
        if (this.state.memoExpanded !== status.data.showMemo) {
          obj.memoExpanded = status.data.showMemo
        }
      }
    }
    if (Object.keys(obj).length > 0) {
      this.setState(obj)
    }
  }

  onCiteChange(status) {
    let obj = {}
    if (status.types.includes('activeBlockCite')) {
      obj.isActive = status.data.blockId === this.props.bid
    }
    if (
      status.types.includes('deactiveCite') ||
      status.types.includes('activeEventsCited') ||
      status.types.includes('activePropsCite') ||
      status.types.includes('activeJengaCite')
    ) {
      obj.isActive = false
    }
    if (
      status.types.includes('changeBlockCite') &&
      status.data.affectBlockId === this.props.bid
    ) {
      this.forceUpdate()
    }
    if (Object.keys(obj).length > 0) {
      this.setState(obj)
    }
  }

  getIsActive() {
    return (
      citeStores.curCite &&
      citeStores.curCite.blockId === this.props.bid &&
      citeStores.curCite.type === 'blockCite'
    )
  }

  hasBlockCite() {
    let curNodeId = this.props.eventNodeId || this.state.curEventNodeId
    let result = false
    let eventNode = getEventNodeById(curNodeId)
    if (
      eventNode &&
      eventNode._cite &&
      eventNode._cite.events &&
      eventNode._cite.events[this.props.bid]
    ) {
      result = true
    }
    return result
  }

  onToggleBlockCite() {
    let curNodeId = this.props.eventNodeId || this.state.curEventNodeId
    if (this.state.isActive) {
      citeActions.deactiveAllCite({})
    } else {
      citeActions.activeBlockCite({
        nodeId: curNodeId,
        blockId: this.props.bid
      })
    }
  }

  render() {
    return shouldCite && this.hasBlockCite() ? (
      <button
        className={cls('btn-clear btn-block-cite', {
          active: this.state.isActive,
          'memo-expanded': this.state.memoExpanded
        })}
        onClick={this.onToggleBlockCite}
      />
    ) : null
  }
}
