<!-- im服务端入口 -->
<template>
    <Card>

    <div class="imServer-wrapper">
        <main class="imServer-main">
            <im-record class="item im-record" :chatDataList="storeChatEnlist" @selectedChat="selectedChat" @searchKey="searchKey"></im-record>
            <im-chat v-if="storeChatEnlist.length" :storeSelectedChatEn="storeSelectedChatEn" ref="im_chat" class="item im-chat" @send="sendSocket"></im-chat>
        </main>
    </div>
    </Card>
</template>

<script >
import imRecord from './imServer/imRecord.vue'
import imChat from './imServer/imChat.vue'
export default {
  components: {
    imRecord: imRecord,
    imChat: imChat
  },
  data () {
    return {
      group: {},
      scoketList: {

      },
      storeChatEnlist: [], // 当前会话列表
      storeSelectedChatEn: {},
      selectIndex: '',
      socket: null,
      timeout: 5000, // 多少秒执行检测
      timeoutObj: null, // 检测服务器端是否还活着
      lockReconnect: false, // 避免重复连接
      status: null, // websocket是否关闭
      reconnectNumber: 0,
      reconnectNumberMax: 100,
      is_open_socket: false,
      isRefs: false,
      timer: ''
    }
  },
  computed: {
    customerId () {
      return this.$store.state.admin.uid
    }
  },
  watch: {},
  methods: {
    initRequest () {
      if (navigator.onLine) {
        this.requestData()
        this.reconnectNumber++
      } else {
        this.$Message.warning('请检查网络！')
      }
    },
    reset () {
      // 清除定时器重新发送一个心跳信息
      clearTimeout(this.timeoutObj)
      this.start()
    },
    // 开始心跳
    start () {
      this.timeoutObj = setTimeout(() => {
        // 这里发送一个心跳，后端收到后，返回一个心跳消息，
        // onmessage拿到返回的心跳就说明连接正常
        let obj = {
          content: 'webscoket心跳',
          type: 120
        }
        obj.fromId = this.$store.state.admin.uid
        obj.fromName = this.$store.state.admin.account
        obj.fromImage = ''
        obj.toId = this.group.groupId
        obj.msgType = obj.type
        this.socket.send(JSON.stringify(obj))
      }, this.timeout)
    },
    // 重连  连接失败时会重连 连接错误时会重连
    reconnect () {
      // 防止多个方法调用，多处重连
      if (this.lockReconnect) {
        return
      };
      if (this.reconnectNumber > this.reconnectNumberMax) {
        this.$Message.warning('网站服务器波动，请稍后再试')
        return
      }
      this.lockReconnect = true
      console.log('准备重连')
      // 没连接上会一直重连，设置延迟避免请求过多
      this.reconnectTimeOutObj = setTimeout(() => {
        // 重新连接
        this.initRequest()
        this.lockReconnect = false
      }, 4000)
    },
    selectedChat (data) {
      this.group = data.group
      this.storeSelectedChatEn = data
    },

    sendSocket (rs) {
      let msg = {
        fromId: this.$store.state.admin.uid,
        fromName: this.$store.state.admin.account,
        fromImage: '',
        toId: this.group.groupId,
        content: rs.msg.content,
        msgType: rs.msg.msgType,
        status: 0
      }
      console.log(this.storeChatEnlist[this.selectIndex])
      // this.storeChatEnlist[this.selectIndex].messageList.push(msg)

      // console.log(msg)
      this.scoketList[this.group.groupId].send(JSON.stringify(msg))
    },
    initTold () {
      if (typeof (WebSocket) === 'undefined') {
        this.$Message.warning('您的浏览器不支持socket')
      } else {
        // 实例化socket
        let protocol = 'ws://'
        if (window.location.protocol === 'https:') {
          protocol = 'wss://'
        }
        this.socket = new WebSocket(`${protocol}${window.location.host}/contact/mallcustomer/ws/${this.customerId}`)
        console.log(this.socket)
        // 监听socket连接
        this.socket.onopen = this.openList
        // 监听socket错误信息
        this.socket.onerror = this.errorList
        // 监听socket消息
        this.socket.onmessage = this.getMessageList
      }
    },
    openList () {
      console.log('列表组socket连接成功')
    },
    errorList () {
      console.log('连接错误')
    },
    getMessageList (msg) {
      console.log('列表' + msg.data)
      this.requestData()
    },
    connectSocketInit (groupId, index) {
      this.selectIndex = index
      let _this = this
      if (groupId) {
        let protocol = 'ws://'
        if (window.location.protocol === 'https:') {
          protocol = 'wss://'
        }
        this.scoketList[groupId] = new WebSocket(`${protocol}${window.location.host}/contact/mallcustomer/websocket/${this.customerId}/${groupId}`)
        this.scoketList[groupId].onopen = function (msg) {
          console.log('组连接成功')
          _this.start()
          _this.is_open_socket = true
        }
        this.scoketList[groupId].onmessage = function (res) {
          _this.reset()
          let obj = JSON.parse(res.data)
          if (obj.msgType !== 120) {
            // _this.$nextTick(function () {
            //   console.log(this)
            //   _this.$refs.im_chat.goEnd()
            // })
            if (!_this.isRefs) {
              let timer = setInterval(() => {
                if (_this.$refs.im_chat) {
                  _this.$refs.im_chat.goEnd()
                  clearInterval(timer)
                  _this.isRefs = true
                }
              }, 100)
            } else {
              _this.$refs.im_chat.goEnd()
            }
            let data = _this.storeChatEnlist[index]

            if (groupId !== _this.customerId && groupId !== _this.group.groupId) {
              data.newsNumber++
            }
            if (groupId !== _this.customerId) {
              data.messageList.push(obj)
            }
            _this.$set(_this.storeChatEnlist, index, data)
          }
        }
        this.scoketList[groupId].onerror = function () {
          _this.reconnectNumber = 0
          if (_this.is_open_socket) {
            _this.reconnect()
          }
        }
        this.scoketList[groupId].onClose = function () {
          _this.reconnectNumber = 0
          if (_this.is_open_socket) {
            _this.reconnect()
          }
        }
      }
    },
    searchKey (key) {
      this.requestData(key)
    },
    requestData (keyWord = '') {
      this.api({
        apiName: 'customerList',
        postdata: { userId: this.$store.state.admin.uid, keyWord: keyWord },
        success: (res) => {
          this.storeChatEnlist = res.data
          // console.log(this.storeChatEnlist)
          if (res.data.length) {
            for (let i = 0, len = this.storeChatEnlist.length; i < len; i++) {
              this.storeChatEnlist[i].newsNumber = 0
              this.connectSocketInit(this.storeChatEnlist[i].group.groupId, i)
              for (let j = 0, len = this.storeChatEnlist[i].messageList.length; j < len; j++) {
                this.storeChatEnlist[i].messageList[j].status = 2
              }
            }
            this.group = res.data[0].group
            this.storeSelectedChatEn = res.data[0]
          }
        }
      })
    }
  },
  mounted () {
    // console.log(this.$refs.im_chat.$re)
    // this.$refs.im_chat.goEnd()
    // const timers = setInterval(() => {
    //   this.requestData()
    // }, 1500)
    // this.$once('hook:beforeDestroy', () => {
    //   clearInterval(timers)
    // })
    this.requestData()
    this.initTold()
  },
  beforeDestroyed () {

  }
}
</script>

<style lang="less">
@import './common/css/base.less';

.imServer-wrapper {
    #common-wrapper();
}

.imServer-wrapper {
    width: 800px;
    height: 650px;
    box-shadow: 0px 0px 12px #c2d6da;
    border:1px solid #e6e6e6;
    border-right: none;
    overflow: hidden;
    .imServer-main {
        height: 100%;
        max-width: 100%;
        position: relative;
        & > .item {
            float: left;
            border-right: 1px solid #e6e6e6;
            height: 100%;
        }
        & > .im-record {
            width: 280px;
        }
        & > .im-chat {
            width: calc(~'100% - 280px');
        }
    }
}
</style>
