import React, { Component } from 'react'
import { connect } from 'dva'
import { Icon, Modal, Badge, List, Avatar, Button, Pagination, Card, notification } from 'antd'
import IFComponent from '../common/IFComponent'
import Socket from '../utils/socket'
import { initFilter } from '../utils/common'
import { cloneDeep } from 'lodash'

class MsgNotice extends Component {
  constructor (props) {
    super(props)
    this.state = {
      visible: false,
      currentNoticeDetail: null,
      current: 1
    }
  }

  componentDidMount () {
    this.refOfSocket = new Socket({
      url: this.props.webSocketHost,
      onmessage: this.handleWebSocketData
    })
  }

  componentWillUnmount () {
    this.refOfSocket.close()
  }

  /**
   * 处理 websocket 的消息
   * @param {*} res
   */
  handleWebSocketData = (res) => {
    if (res) {
      const { TypeCode, Data } = JSON.parse(res)
      if (TypeCode === 'M001' && Data) {
        const __html = Data.Message.replace(/[\n\r]/g, '<br/>')
        switch (Data.ShowInfoType) {
          case 0:
            this.addNotification(Data)
            Modal.info({
              title: Data.Title || '通知',
              content: <div dangerouslySetInnerHTML={{ __html }} />,
              onOk: () => {
                this.acceptedNotification(Data)
              }
            })
            break
          case 1:
            notification.info({
              message: Data.Title || '通知',
              description: <div dangerouslySetInnerHTML={{ __html }} />
            })
            this.addNotification(Data)
            this.acceptedNotification(Data)
            break
          default:
            break
        }
      }
    }
  }

  /**
   * 显示隐藏通知面板
   * @param {*} visible
   */
  toggleVisible = (visible) => {
    this.setState({
      visible,
      currentNoticeDetail: null
    })
  }

  /**
   * 消息详情显示和已读
   * @param {*} value
   */
  onReading = (value) => {
    this.setState({ currentNoticeDetail: value })
    !value.IsAccepted && this.acceptedNotification(value)
  }

  /**
   * 渲染弹窗 footer
   */
  renderFooter = () => {
    const { login, dispatch } = this.props
    const { OrgId, userId } = login
    const { TotalCount, ErrorMessage } = login.Notifications || {}
    const { currentNoticeDetail, current } = this.state
    const pageConfig = {
      key: 'pagination',
      size: 'small',
      total: TotalCount,
      current,
      showTotal: total => `共 ${total} 条, 未读 ${ErrorMessage || 0} 条`,
      onChange: page => {
        dispatch({
          type: 'login/getNotices',
          payload: initFilter(OrgId, '', 'CREATE_TIME', 1, page, userId)
        }).then(res => {
          if (res && res.IsSuccessful) {
            this.setState({ current: page })
          }
        })
      }
    }

    if (currentNoticeDetail) {
      return (
        <Button key='cancel' onClick={() => this.setState({ currentNoticeDetail: null })}>
          返回列表
        </Button>
      )
    }

    return <Pagination {...pageConfig} />
  }

  /**
   * websocket 新通知追加到列表中
   * @param {*} data
   */
  addNotification = (data) => {
    const { dispatch, login } = this.props
    let arr = JSON.parse(JSON.stringify(login.Notifications))
    !arr && (arr = { Data: [], TotalCount: 0 })
    arr.Data.splice(0, 0, data)
    data.NotificatoinType === 0 && dispatch({
      type: 'login/save',
      payload: {
        Notifications: arr
      }
    })
  }

  /**
   * websocket 新通知设置已读
   * @param {*} data
   * @param {*} cb
   */
  acceptedNotification = (data) => {
    const { NotificationId } = data
    const { login, dispatch } = this.props
    const { OrgId, userId } = login
    const json = initFilter(OrgId, NotificationId, '', 0, 1, userId)
    dispatch({
      type: 'app/acceptNotification',
      payload: json,
      onComplete: (res) => {
        if (res) {
          const copyData = cloneDeep(login.Notifications)
          const errorMessage = Number(copyData.ErrorMessage)
          const findData = copyData.Data.find(item => item.NotificationId === NotificationId)
          if (findData) {
            findData.IsAccepted = true
            errorMessage > 0 && (copyData.ErrorMessage = errorMessage - 1)
            dispatch({
              type: 'login/save',
              payload: {
                Notifications: copyData
              }
            })
          }
        }
      }
    })
  }

  render () {
    const { Notifications } = this.props.login
    const { Data = [], ErrorMessage } = Notifications || {}
    const { visible, currentNoticeDetail } = this.state

    return (
      <React.Fragment>
        <Badge dot={ErrorMessage > 0} onClick={() => this.toggleVisible(true)}>
          <Icon type='bell' className={`msg-notice__icon ${this.props.theme}`} />
        </Badge>
        <Modal
          title='消息'
          maskClosable={false}
          visible={visible}
          wrapClassName='msg-notice__modal'
          bodyStyle={{ padding: 0 }}
          footer={this.renderFooter()}
          onCancel={() => this.toggleVisible(false)}
        >
          <IFComponent
            IF={!currentNoticeDetail}
            ELSE={
              <Card bordered={false}>
                <Card.Meta
                  avatar={<Avatar>{currentNoticeDetail ? String(currentNoticeDetail.UserName)[0] || '?' : ''}</Avatar>}
                  title={currentNoticeDetail ? currentNoticeDetail.Time + ' ' + currentNoticeDetail.Title : '通知'}
                  description={currentNoticeDetail ? currentNoticeDetail.Message : '无'}
                />
              </Card>
            }
          >
            <List
              dataSource={Data}
              renderItem={item => (
                <List.Item
                  className='msg-notice__list'
                  onClick={() => this.onReading(item)}
                  actions={
                    <IFComponent IF={!item.IsAccepted}>
                      <a onClick={(e) => {
                        e.stopPropagation()
                        this.acceptedNotification(item)
                      }}
                      >标记已读</a>
                    </IFComponent>
                  }
                >
                  <List.Item.Meta
                    avatar={<Avatar>{String(item.UserName)[0] || '?'}</Avatar>}
                    title={`${item.Title ? item.Time + ' ' + item.Title : '通知'}`}
                    description={<div className='msg-notice__msg'>{item.Message || '无'}</div>}
                  />
                </List.Item>
              )}
            />
          </IFComponent>
        </Modal>
      </React.Fragment>
    )
  }
}

export default connect(({ login }) => ({ login }))(MsgNotice)
