import Taro, { Component } from '@tarojs/taro';
import './index.scss'

import dayjs from 'dayjs'
import MsgItem from './msgItem'
import FormIdCollector from '@components/formIdCollector'
import BackHomeBtn from '@components/BackHomeBtn'

import { queryChatHistory } from '@services/chat'
import { uploadFiles, fetch } from '@utils/request'
import { deepClone } from '@utils/tools'

import { savePoint, updatePoint } from '@services/common'
import { connect } from '@tarojs/redux'
import { ROLE_CODE } from '@constants/user'
import { API_QUERY_USERINFO_BYID } from '@constants/api'
import { dispatchCardInfo } from '@actions/card'

// import { dispatchUserPhone } from '@actions/user'
import getUserPhone from '@utils/getUserPhone'

import socket, { MESSAGETYPE } from '@utils/im'
import ready from '@utils/ready'
import store from '../../store'

@connect(state => (
  { ...state.card, ...state.user, ...state.login }),
  { dispatchCardInfo }
)
export default class Chat extends Component {

  config = {
    navigationBarTitleText: ''
  }
  state = {
    msgList: [],
    inputText: '',
    messageType: MESSAGETYPE.TEXT,
    // chatInputHeight: 120,
    marginTop: 0,
    visExtra: false,
    scrollTop: 0,
    noData: false,

    pagination: {
      pageNumber: 1,
      pageSize: 20,
    },
    msgNum: 0, // 发送接收信息数量
    // receivePerson: null, //接收人id
    // receiveName: '', // 接受人name
    visiblePrompt: false,
    prompts: ['现在在售的户型有哪些？', '现在项目均价多少钱一平？', '项目周边的配套有哪些？', '未来周边规划的配套有哪些？'],
    recordId: null,

    noChatting: false,  // 异常
    chatting: null, // 当前聊天对象
    me: null, // 自己
  }

  originList = []
  componentWillMount() {
    savePoint({
      event: 'detail',
      eventType: 'info',
      propertyName: '在线咨询',
      data: '{}'
    }).then(res => {
      this.setState({
        recordId: res.recordId
      })
      console.log('在线咨询')
    })
  }

  componentDidMount() {
    ready.queue(() => {
      const { sendId, sendName, receiverId, receiverName } = this.$router.params
      const me = this.props.userInfo.person
      const { personId: mineId } = me
            
      // 系统异常
      if (!sendId || !receiverId) {
        Taro.showToast({
          title: '无聊天对象, 请退出重试',
          icon: 'none',
          duration: 5000
        })

        this.setState({ noChatting: true })
        return;
      }

      // 自己跟自己聊
      if (sendId === mineId && receiverId === mineId) {
        Taro.showToast({
          title: '暂不支持自我聊天',
          icon: 'none',
          duration: 5000
        })

        this.setState({ noChatting: true })
        return;
      }

      // 非当前人员页面
      if (sendId != mineId && receiverId != mineId) {
        Taro.showToast({
          title: '数据获取错误, 请退出重试',
          icon: 'none',
          duration: 5000
        })

        this.setState({ noChatting: true })
        return;
      }

      let chatting = {
        personId: sendId === mineId ? receiverId : sendId,
        nickname: sendId === mineId ? decodeURIComponent(receiverName) : decodeURIComponent(sendName),
        avatarurl: null,
        personType: null,
      }

      // 设置页面 title
      Taro.setNavigationBarTitle({ title: chatting.nickname || '聊天' })

      // 获取聊天对象信息
      fetch({ url: `${API_QUERY_USERINFO_BYID}/${chatting.personId}` }).then(res => {
        // res 为 person 信息
        chatting.avatarurl = res.avatarurl
        chatting.personType = res.personType

        this.setState({ chatting, me }, () => {
          this.loadList(res => {
            this.toBottom()
  
            const { records } = res
            const newMsg = records[0]
            const isCardMsg = newMsg && newMsg.messageType === MESSAGETYPE.CARD
  
            // 如果最新一条消息不是卡片类型 则自动发送卡片信息
            if (!isCardMsg) {
              setTimeout(() => {
                this.sendCardMsg()
              }, 500)
            }
          });
        });
      })

      socket.wss.onMessage(res => {    
        const data = JSON.parse(res.data)

        console.log('receive message ==>', data)

        if (data.sendPerson != chatting.personId) {
          // store.dispatch({ type: INCREASE_UNREADNUM })
        } else {
          this.handlerRecive(data)
        }
      })
    })
  }

  componentWillUnmount() {
    // socket.closeSocket()
    const { recordId } = this.state
    recordId && updatePoint(recordId)
  }

  sendCardMsg = () => {
    const { me, chatting } = this.state

    // 本人是置业顾问, 不做卡片发送操作
    if (me.personType === ROLE_CODE['CONSULTANT']) {
      return;
    }

    // 本人不是置业, 对方必然是置业
    this.props.dispatchCardInfo(chatting.personId).then(res => {
      const chattingName = res.name || chatting.nickname

      // 发送 卡片 消息
      socket.sendNotice({
        sendPerson: chatting.personId,
        receivePerson: me.personId,
        message: `您好，我是${chattingName},有什么可以帮助您的吗?您可以在这里跟我实时沟通哦~`,
        messageType: MESSAGETYPE.CARD,
        createDate: new Date().valueOf(),
      }, res => {
        console.log('发送成功')
        this.appendData(payload)
      })

      this.setState({
        nickname: chattingName,
        avatarurl: res.picture || res.avatar,
        personType: res.personType,
      })
    })
  }

  getPhoneNumber = (e) => {
    getUserPhone(e, (phoneNumber) => {
      const selfPhone = tel || phone || phoneNumber
      if (!selfPhone) {
        Taro.showToast({
          icon: 'none',
          title: '获取手机号失败'
        })
        return
      }

      this.sendMessage(`我的手机号是${selfPhone}，请来电联系我哦~`)
    })
  }

  redirectTo = () => {
    const length = getCurrentPages().length
    setTimeout(() => {
      if (length > 1) {
        Taro.navigateBack({ delta: 1 })
      } else {
        Taro.switchTab({ url: '/pages/project/index' })
      }
    }, 500)
  }

  handlerRecive = (data) => {
    // debugger
    this.appendData(data)
  }

  loadList = (cb) => {
    if (this.loading) return
    this.loading = true
    const { pagination, chatting } = this.state
    const payload = Object.assign(pagination, { chatWith: chatting.personId })

    Taro.showLoading({ title: '正在加载' })
    queryChatHistory(payload).then(res => {
      const { size, pages, current, records } = res
      console.info('加载数据成功', res)
      let list = this.dealChatData(records)

      this.setState({
        pagination: {
          pageNumber: current,
          pageSize: size,
          pages
        },
        noData: (pages > 0 && records.length <= 0 && current > pages) ? true : false,
        msgList: list
      })

      setTimeout(() => {
        Taro.hideLoading()
        this.loading = false

        if (cb instanceof Function) {
          cb(res)
        } else {
          this.setState({
            scrollTop: Math.random() + 1
          })
        }
      }, 500)
    })
  }

  formatData = (data) => {
    let _map = {}
    let _rows = deepClone(data)
    let _time = null

    _rows.forEach((item, index) => {
      let curTime = dayjs(item.createDate).valueOf()
      let nextItem = _rows[index + 1]

      if (index === 0) {
        _time = curTime
        _map[_time] = [item]
      }

      if (nextItem) {
        let nextTime = dayjs(nextItem.createDate).valueOf()
        if (nextTime - _time <= (5 * 60 * 1000)) {
          _map[_time].push(nextItem)
        } else {
          _time = nextTime
          _map[nextTime] = [nextItem]
        }
      }
    })

    // 时间从近到远排序
    let keys = Object.keys(_map).sort((a, b) => b - a)

    // 格式化数据
    let newArr = []
    keys.map(key => {
      let obj = {
        id: key,
        time: key,
        list: _map[key]
      }
      newArr.push(obj)
    })

    // 按倒叙排列
    return newArr.reverse()
  }

  dealChatData = (data, type) => {
    let list = null
    if (type == 'new') {
      list = [...(data || []), ...this.originList]
    } else {
      list = [...this.originList, ...(data || [])]
    }

    this.originList = deepClone(list)
    list = this.formatData(list.reverse())

    return list
  }

  toBottom = () => {
    // 使页面滚动到底部
    Taro.createSelectorQuery().select('.msg__list').boundingClientRect(rect => {
      this.setState({
        scrollTop: rect.height
      })
    }).exec()
  }

  bindAlbumClick = (e) => {
    e.stopPropagation()
    Taro.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: res => {
        uploadFiles(res.tempFilePaths).then(data => {
          this.sendMessage(data[0], MESSAGETYPE.IMAGE)

          this.setState({
            marginTop: 0,
            visExtra: false,
          })
        })
      }
    })
  }

  sendMessage = (message, messageType = MESSAGETYPE.TEXT) => {
    const { me, chatting } = this.state

    const payload = {
      sendPerson: me.personId,
      receivePerson: chatting.personId,
      message,
      messageType,
      createDate: new Date().valueOf(),
    }

    socket.sendNotice(payload, res => {
      console.log('发送成功')
      this.appendData(payload)
    })
 
    this.setState({
      inputText: '',
      // msgList: list
    }, this.toBottom)
  }

  appendData = (data) => {
    const { msgList } = this.state

    this.originList.unshift(data)

    let list = deepClone(msgList)
    let lastMsg = list[list.length - 1]

    data.createDate = dayjs(data.createDate).valueOf()

    if (lastMsg && (data.createDate - lastMsg.time <= (5 * 60 * 1000))) {
      lastMsg.list.push(data)
    } else {
      list.push({
        time: data.createDate,
        list: [data]
      })
    }

    this.setState({ msgList: list })
  }

  handleIssueClick = (message, e) => {
    this.sendMessage(message)
  }

  bindSendBtn = (e) => {
    // e.stopPropagation()
    this.sendMessage(this.state.inputText, MESSAGETYPE.TEXT)
    this.hideExtraArea()
    savePoint({
      event: 'essential',
      eventType: 'info',
      propertyName: '咨询关键内容',
      data: '{}'
    }).then(res => {
      console.log('咨询关键内容')
    })
  }

  bindTextInput = (e) => {
    this.setState({
      inputText: e.detail.value
    })
  }

  bindInputConfirm = (e) => {
    e.stopPropagation()
    this.sendMessage(this.state.inputText, MESSAGETYPE.TEXT)
  }

  showExtraArea = (e) => {
    e.stopPropagation()
    this.setState({
      visExtra: true,
      marginTop: -240
    })
  }

  hideExtraArea = (e) => {
    e && e.stopPropagation()
    if (!this.state.visExtra) {
      return
    }

    this.setState({
      visExtra: false,
      marginTop: 0
    })
  }

  onScrolltoupper = () => {
    const { pagination } = this.state
    const { pageNumber, pages } = pagination

    if (pageNumber >= pages) {
      return
    }

    this.setState({
      pagination: Object.assign(pagination, { pageNumber: (pageNumber + 1) })
    }, () => {
      this.loadList()
    })
  }

  toHomePage() {
    Taro.switchTab({
      url: '/pages/project/index'
    })
  }

  togglePromptVisible = (flag) => {
    this.setState({
      visiblePrompt: !!flag
    })
    savePoint({
      event: 'common',
      eventType: 'info',
      propertyName: '常见问题',
      data: '{}'
    }).then(res => {
      console.log('常见问题')
    })
  }

  render() {
    const { marginTop, visiblePrompt, prompts, msgList, noChatting } = this.state

    // 如果有错误, 不显示内容
    if (noChatting) return null;

    const extraWrap = (
      <View className="import-bottom">
        <View className="extra-item" onClick={this.bindAlbumClick}>
          <Image mode="aspectFit" className="extra-item__img" src={require('@assets/chat/choose_picture.png')} />
          <Text className="extra-item__text">相册</Text>
        </View>
      </View>
    )

    return (
      <View className='chat'>

        <View className="prompt__btn" onClick={this.togglePromptVisible.bind(this, true)}>
          <Text className="text">常见问题</Text>
        </View>

        <BackHomeBtn style={{ right: '3%' }}></BackHomeBtn>
        {
          visiblePrompt && (
            <View className="prompt" onClick={this.togglePromptVisible.bind(this, false)}>
              <View className="prompt__content">
                {/* <View className="prompt__title">常见问题咨询</View> */}
                {prompts.map((text, index) => (
                  <View
                    key={index}
                    className="prompt__item"
                    onClick={this.handleIssueClick.bind(this, text)}>
                    <Text>{text}</Text>
                    <Text className="iconfont icon-tubiao- fasong"></Text>
                  </View>
                ))}
              </View>
            </View>
          )
        }


        <ScrollView
          scrollY
          enable-back-to-top
          upper-threshold={100}
          scroll-with-animation
          scroll-top={scrollTop}
          onScrolltoupper={this.onScrolltoupper}
          onClick={this.hideExtraArea}
          className='chat__wrap'
          style={{
            marginTop: marginTop + 'rpx'
          }}>

          <View className="msg__list">
            {noData && <View className="no__data">没有更多数据了~</View>}
            {msgList.map(item => <MsgItem item={item} key={item.id} getPhone={this.getPhoneNumber}></MsgItem>)}
          </View>


        </ScrollView>

        <View className="chat__import">
          <View className="import-top">
            <Input
              className="import-top__input"
              cursor-spacing={6}
              value={inputText}
              onInput={this.bindTextInput}
              onConfirm={this.bindInputConfirm}
              placeholder='发送消息'
            />
            <Text className="import-top__extra iconfont icon-Add" onClick={this.showExtraArea}></Text>
            <FormIdCollector count={1}>
              <Button size="mini" className="import-top__submit" onClick={this.bindSendBtn}>发送</Button>
              {/* <Image src={require('@assets/news/fasong.png')} className='submit-img'  onClick={this.bindSendBtn}></Image> */}
            </FormIdCollector>
          </View>
          {visExtra && extraWrap}
        </View>
      </View>
    );
  }
}
