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 } 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 { dispatchCardInfo } from '@actions/card'

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

import socket from '@utils/im'
import ready from '@utils/ready'

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

  config = {
    navigationBarTitleText: ''
  }
  state = {
    msgList: [],
    inputText: '',
    imageFile: '',
    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,

    sendPersonId: null,
    sendPersonName: null,
    receivePersonId: null,
    receivePersonName: 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 { scene } = Taro.getStorageSync('router')


      /**
       * 当 scene ==1014 时，是从服务消息直接进入聊天页面，
       * 则id为 sendId,反之是为receiverId
       */
      const fromTempleteMsg = scene == 1014
      let sendPersonId = fromTempleteMsg ? receiverId : sendId
      let sendPersonName = fromTempleteMsg ? receiverName : sendName
      let receivePersonId = fromTempleteMsg ? sendPersonId : receiverId
      let receivePersonName = fromTempleteMsg ? sendName : receiverName

      // debugger
      // if (!receivePersonId) {
      //   Taro.showToast({ title: 'receivePersonId不存在' })
      //   this.redirectTo()
      //   return
      // }

      // if (receivePersonId === personId) {
      //   Taro.showToast({ title: '你不能自己跟自己聊天~' })
      //   this.redirectTo()
      //   return
      // }

      Taro.setNavigationBarTitle({
        title: decodeURIComponent(receivePersonName) || '聊天'
      })

      this.setState({ sendPersonId, sendPersonName, receivePersonId, receivePersonName }, () => {
        this.loadList(res => {
          this.toBottom()

          const { records } = res
          const newMsg = records[0]
          const isCardMsg = newMsg && newMsg.messageType === 'card'

          // 如果最新一条消息不是卡片类型 则自动发送卡片信息
          if (!isCardMsg) {
            setTimeout(() => {
              this.sendCardMsg()
            }, 500)
          }
        });
      });

      socket.wss.onMessage(res => {
        const data = JSON.parse(res.data)
        // debugger
        this.handlerRecive(data)
      })
    })
  }

  sendCardMsg() {
    // const { userInfo: { person: { personId, personType } } } = this.props
    // const isConsultant = (personType === ROLE_CODE['CONSULTANT'])
    // const { receivePerson } = this.state
    // const cardId = isConsultant ? personId : receivePerson
    const { userInfo: { person: { personType: sendPersonType } } } = this.props
    const { receivePersonId, receivePersonName, sendPersonId } = this.state
    this.props.dispatchCardInfo(receivePersonId).then(res => {
      // debugger
      // 本人不是置业顾问且对方是置业顾问 则对方向我发送消息
      const { personType: receivePersonType } = res
      const hasSend = (sendPersonType != ROLE_CODE['CONSULTANT'] && receivePersonType == ROLE_CODE['CONSULTANT'])
      if (hasSend) {
        let payload = {
          sendPerson: receivePersonId,
          receivePerson: sendPersonId,
          message: `您好，我是${receivePersonName},有什么可以帮助您的吗?您可以在这里跟我实时沟通哦~`,
          messageType: 'card',
          createDate: new Date().valueOf(),
        }
        // 发送消息
        socket.sendNotice(payload)
      }
    })
  }

  getPhoneNumber = (e) => {
    const { userInfo: { person: { phone, sendPersonId, receivePersonId } } } = this.props
    // const { receivePerson } = this.state
    getUserPhone(e, (phoneNumber) => {
      const selfPhone = phone || phoneNumber
      if (!selfPhone) {
        Taro.showToast({
          icon: 'none',
          title: '获取手机号失败'
        })
        return
      }

      let payload = {
        sendPerson: sendPersonId,
        receivePerson: receivePersonId,
        message: `我的手机号是${selfPhone}，请来电联系我哦~`,
        messageType: 'text',
        createDate: new Date().valueOf()
      }

      // 发送消息
      socket.sendNotice(payload, res => {
        console.log('发送成功')
        this.appendData(payload)
      })
    })
  }

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

  componentWillUnmount() {
    // socket.closeSocket()
    const { recordId } = this.state
    recordId && updatePoint(recordId)
  }
  // createSocket() {
  //   const { userInfo: { person: { personId } } } = this.props
  //   socket.createSocket({
  //     id: personId,
  //     success: (res) => {
  //       console.log('success', res)
  //     },
  //     close: (res) => {
  //       console.log('close', res)
  //     },
  //     receive: (res) => {
  //       console.log('receive', res)
  //       let data = JSON.parse(res.data)
  //       this.handlerRecive(data)
  //     },
  //     fail: (res) => {
  //       console.log('fail', res)
  //     }
  //   })
  // }

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

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

    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) {
    debugger
    e.stopPropagation()
    Taro.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: res => {
        uploadFiles(res.tempFilePaths).then(data => {
          this.setState({
            marginTop: 0,
            messageType: 'image',
            visExtra: false,
            imageFile: data[0]
          }, this.onSendMsg)
        })
      }
    })
  }

  onSendMsg() {
    const { inputText, imageFile, messageType, sendPersonId, receivePersonId } = this.state

    if (!inputText && !imageFile) return

    let message = ''
    if (messageType === 'text') {
      message = inputText
    } else if (messageType === 'image') {
      message = imageFile
    }

    let payload = {
      sendPerson: sendPersonId,
      receivePerson: receivePersonId,
      message,
      messageType,
      createDate: new Date().valueOf(),
    }

    payload.chatId = payload.createDate

    // 发送消息
    socket.sendNotice(payload, res => {
      console.log('发送成功')

      this.appendData(payload)
      // this.setState({
      //   inputText: '',
      //   imageFile: '',
      //   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({
      inputText: '',
      imageFile: '',
      msgList: list
    }, this.toBottom)
  }

  handleIssueClick(message, e) {
    // e.stopPropagation()
    const { sendPersonId, receivePersonId } = this.state
    let payload = {
      sendPerson: sendPersonId,
      receivePerson: receivePersonId,
      message,
      messageType: 'text',
      createDate: new Date().valueOf()
    }

    payload.chatId = payload.createDate
    socket.sendNotice(payload, res => {
      console.log('发送成功')
      this.appendData(payload)
    })
  }

  bindSendBtn(e) {
    // e.stopPropagation()
    this.setState({
      messageType: 'text'
    }, this.onSendMsg)
    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.onSendMsg()
  }

  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 } = this.state
    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>
    );
  }
}