import React from 'react'
import cls from 'classnames'
import i18n from 'i18next'
import newEventActions from 'actions/newEvent'
import newEventStores from 'stores/newEvent'
import { getEventBlockByBid, getEventNodeById } from 'stores/funcs/newEvent'
import { shallowEqualImmutable } from 'utils/utils'
import { autoTextarea } from 'utils/commons/autoTextarea'

class EditMemo extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      value: props.value
    }
    this.textarea = React.createRef()
    this.resetTextarea = this.resetTextarea.bind(this)
    this.onChange = this.onChange.bind(this)
    this.onBlur = this.onBlur.bind(this)
    this.getZIndex = this.getZIndex.bind(this)
  }

  componentDidMount() {
    if (this.textarea && this.textarea.current) {
      this.resetTextarea()
    }
  }

  componentDidUpdate(preProps) {
    if (preProps.value !== this.props.value) {
      this.setState(
        {
          value: this.props.value
        },
        () => {
          if (this.textarea && this.textarea.current) {
            this.resetTextarea()
          }
        }
      )
    }
  }

  resetTextarea() {
    this.textarea.current.removeAttribute('style')
    delete this.textarea.current._length
    delete this.textarea.current.currHeight
    autoTextarea(this.textarea.current, 0, undefined)
  }

  onChange(e) {
    let val = e && e.target ? e.target.value : e
    this.setState({
      value: val
    })
  }

  onBlur() {
    this.props.onChange && this.props.onChange({ memo: this.state.value })
  }

  getZIndex() {
    let max = 99999
    if (this.props.active) {
      return max
    } else if (this.props.order !== undefined) {
      return max - (this.props.order + 1)
    } else {
      return 0
    }
  }

  render() {
    return (
      <div
        style={{ zIndex: this.getZIndex() }}
        className={cls('block-memo f--hlc', this.props.className, {
          active: this.props.active
        })}
      >
        <textarea
          ref={this.textarea}
          placeholder={i18n.t('EventView.jenga_nav.memo')}
          value={this.state.value}
          className="memo-textarea"
          onChange={this.onChange}
          onBlur={this.onBlur}
        />
      </div>
    )
  }
}

export default class BlockMemo extends React.Component {
  constructor(props) {
    super(props)
    this.curEventNodeId = newEventStores.curEventNodeId
    this.state = {
      expanded: newEventStores.showMemo, // 是否显示memo
      memo: this.getBlockMemo(),
      order: this.getOrder()
    }
    this.onEventChange = this.onEventChange.bind(this)
    this.getOrder = this.getOrder.bind(this)
    this.getBlockMemo = this.getBlockMemo.bind(this)
    this.onChangeMemo = this.onChangeMemo.bind(this)
    this.editContent = this.editContent.bind(this)
  }

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

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

  componentWillUnmount() {
    this.unsubscribe()
  }

  componentDidUpdate(preProps) {
    if (preProps.bid !== this.props.bid) {
      let memo = this.getBlockMemo()
      if (memo !== this.state.memo) {
        this.setState({
          memo: memo
        })
      }
    }
  }

  onEventChange(status) {
    let obj = {}
    if (status && status.types) {
      if (status.types.includes('showMemo')) {
        if (this.state.expanded !== status.data.showMemo) {
          obj.expanded = status.data.showMemo
        }
      }
      if (
        status.types.includes('updateBlockProp') &&
        this.props.bid === status.data.affectBlockId &&
        status.data.prop === 'com'
      ) {
        obj.memo = this.getBlockMemo()
      }
      if (status.types.includes('curEventNodeId')) {
        if (this.curEventNodeId !== status.data.curEventNodeId) {
          this.curEventNodeId = status.data.curEventNodeId
        }
      }
      if (status.types.includes('curEventBlockOrder')) {
        let order = this.getOrder()
        if (order !== this.state.order) {
          obj.order = order
        }
      }
    }
    if (Object.keys(obj).length > 0) {
      this.setState(obj)
    }
  }

  getOrder() {
    let curNodeId = this.props.eventNodeId || this.curEventNodeId
    let eventNode = getEventNodeById(curNodeId)
    if (eventNode) {
      return eventNode.events.order.indexOf(this.props.bid)
    }
    return 0
  }

  getBlockMemo() {
    let bid = this.props.bid
    let curNodeId = this.props.eventNodeId || this.curEventNodeId
    let block = getEventBlockByBid(bid, curNodeId)
    if (block && block.com) {
      return block.com
    }
    return ''
  }

  onChangeMemo(e) {
    if (e && e.memo !== undefined && this.state.memo !== e.memo) {
      this.setState(
        {
          memo: e.memo
        },
        () => {
          let curNodeId = this.props.eventNodeId || this.curEventNodeId
          newEventActions.updateBlockProp({
            nodeId: curNodeId,
            blockId: this.props.bid,
            prop: 'com',
            value: this.state.memo,
            addRecord: true,
            trigger: false
          })
        }
      )
    }
  }

  editContent() {
    return (
      <EditMemo
        className={this.props.className}
        active={this.props.active}
        order={this.state.order}
        value={this.state.memo}
        onChange={this.onChangeMemo}
      />
    )
  }

  render() {
    return this.state.expanded ? this.editContent() : null
  }
}
