<template>
  <div class="c-view">
    <div class="box">
      <div class="box-hd">
        <div class="title-wrap">
          {{isPrivate ? group.privateName : group.groupName}}
          <i class="el-icon-more" v-if="!isPrivate" @click="groupSet = !groupSet"></i>
        </div>
      </div>
      <chat-pin v-bind="pinMsg" @pinMsgClose="pinMsgClose" @scrollToView="scrollToView"></chat-pin>
      <div class="box-bd" :style="{height:scrollHeight - (pinMsg.visible ? 30 : 0) + 'px'} ">
        <div ref="scrollWrap" class="bar" @scroll="handleScroll">
          <div ref="msgWrap" class="scroll-wrapper">
            <div class="msg-wrap">
              <div class="msg-top-more" v-if="lockEnd">
                <em>没有更多了</em>
              </div>
              <div class="msg-top-load" v-if="lockMore && !lockEnd">
                <i class="msg-loading-icon"></i>
              </div>
              <template v-if="group.chatList.length">
                <msg-item v-for="(item ,key) in group.pinList"
                  :key="'pin' + key"
                  v-bind="item"
                  @quoteMsg="quoteMsg"
                  @deleteMsg="deleteMsg"
                >
                </msg-item>
              </template>
              <msg-item v-for="(item, key) in group.chatList"
                :key="key"
                :isPrivate ="isPrivate"
                :msgItem="item"
                v-bind="item"
                @quoteMsg="quoteMsg"
                @deleteMsg="deleteMsg"
                >
              </msg-item>
            </div>
          </div>
        </div>
        <at-me v-if="!isPrivate" :atList="atList" @scrollToMsg="scrollToMsg"></at-me>
        <div class="msg-unread"
          @click="doSetRead"
          v-if="group.unreadNums > 0 && enableScroll">
          <em><i class="el-icon-d-arrow-right"></i>{{group.unreadNums}}条未读消息</em>
        </div>
      </div>
      <input-area ref="inputArea" @toBottom="resizeToBottom"></input-area>
    </div>
    <chat-set
      v-if="group.members && !isPrivate"
      :class="{'move-left': groupSet}">
    </chat-set>
  </div>
</template>

<script>
import Vue from 'vue'
import msgItem from '@/components/msgItem'
import chatPin from '@/components/chatPin'
import atMe from '@/components/chatAt/atme'
import { mapActions, mapState, mapMutations } from 'vuex'
import chatSet from '@/components/chatSet'
import inputArea from './inputArea'
import { getResizeHeight, scrollMsgIntoView } from '@/util/util.js'
import { Button } from 'element-ui'

Vue.component(Button.name, Button)

export default {
  name: 'chatRoom',
  components: {
    msgItem,
    inputArea,
    chatSet,
    chatPin,
    atMe
  },
  props: {
    sessionId: [String, Number]
  },
  watch: {
    sessionId (val) {
      // 切换房间
      this.groupSet = false
      this.lockMore = false
      this.lockEnd = false
      this.enableScroll = false

      this.initRoom()
    },
    unreadNums (val, newval) {
      if (val > 0 && this.isBottom) {
        this.resizeToBottom()
      }
    }
  },
  data () {
    return {
      groupSet: false,
      lockMore: false,
      lockEnd: false,
      enableScroll: false, // 记录滚动条是否激活的状态
      isBottom: true,
      scrollHeight: 100, // 滚动条高度
      isScrollToView: false
    }
  },
  computed: {
    ...mapState([
      'group',
      'userId',
      'userInfo'
    ]),
    ...mapState({
      pinMsg: state => state.group.pinMsg,
      pinList: state => state.group.pinList,
      atList: state => state.group.atList
    }),
    isPrivate () {
      return /-/g.test(this.sessionId)
    }
  },
  mounted () {
    this.scrollHeight = getResizeHeight()
    window.onresize = () => {
      this.scrollHeight = getResizeHeight()
    }
    this.initRoom()
    document.addEventListener('contextmenu', e => e.preventDefault())
  },
  methods: {
    ...mapMutations([
      'initGroup',
      'resetUnreadNums',
      'addChatItem',
      'deleteChatItem',
      'initState',
      'clearAtList'
    ]),
    ...mapActions([
      'getGroupInfo',
      'getNewMsg',
      'getHistoryMsg',
      'doSendMsg',
      'getPrivateNewMsg',
      'getPrivateHistoryMsg',
      'doSendPrivateMsg'
    ]),
    initRoom () {
      this.initState(this.userInfo)
      if (this.isPrivate) {
        this.initPersonChat()
      } else {
        this.initGroupChat()
      }
    },
    /**
     * @des 私聊初始化处理
     */
    async initPersonChat () {
      await this.getPrivateNewMsg()

      this.$nextTick(this.resizeToBottom)
    },
    /**
     * @des 聊天群初始化处理
     */
    async initGroupChat () {
      this.initGroup({
        userId: this.userId,
        groupId: this.sessionId,
        useCache: false
      })

      await this.getGroupInfo()

      await this.getNewMsg()

      this.$nextTick(this.resizeToBottom)
    },
    /**
     * @des 滚动事件监听
     */
    initScrollEvent () {
    },
    /**
     * @des 聊天窗体滚动事件处理集
     */
    async handleScroll (e) {
      // 防止切换房间时触发滚动处理
      if (!this.group.chatList.length) {
        return
      }
      // 防止滚动到置顶消息触发滚动
      if (this.isScrollToView) {
        return
      }
      // 激活滚动条
      this.enableScroll = true
      let totalHeight = this.$refs.msgWrap.offsetHeight
      let scrollTop = e.target.scrollTop

      // 差不多滚动到顶部
      if (scrollTop === 0 && !this.lockMore) {
        if (this.group.endHash !== null) {
          this.lockMore = true
          let res
          if (this.isPrivate) {
            res = await this.getPrivateHistoryMsg()
          } else {
            res = await this.getHistoryMsg()
          }
          if (res === 'end') {
            this.lockEnd = true
          } else {
            let scrollBottom = totalHeight - scrollTop
            this.$nextTick(() => {
              e.target.scrollTop = this.$refs.msgWrap.offsetHeight - scrollBottom
              setTimeout(() => {
                this.lockMore = false
              }, 800)
            })
          }
        }
      }

      // 滚动到底部清空未读消息状态
      if (scrollTop + e.target.offsetHeight > totalHeight) {
        this.isBottom = true
        if (this.group.unreadNums) {
          this.resetUnreadNums()
        }
      } else {
        this.isBottom = false
      }
    },
    /**
     * @des 聊天窗体滚动到底部
     */
    resizeToBottom () {
      this.$refs.scrollWrap.scrollTop = this.$refs.msgWrap.offsetHeight
      this.resetUnreadNums()
      this.isBottom = true
    },
    /**
     * @des 点击，查看未读消息
     * 直接滚动到聊天列表底部
     */
    doSetRead () {
      this.resizeToBottom()
    },
    /**
     * @des 引用某条消息
     */
    quoteMsg (msg) {
      this.$refs.inputArea.inputMsg = msg
    },
    /**
     * @des 某条消息被删除
     */
    deleteMsg (hash) {
      this.deleteChatItem(hash)
    },
    pinMsgClose () {
      this.pinMsg.visible = false
    },
    scrollToView () {
      if (this.pinList.length) {
        let node = this.$refs.msgWrap.querySelector('.msg-item')
        scrollMsgIntoView(this.$refs.scrollWrap, node.offsetTop - (this.pinMsg ? 40 : 10), node)
      } else {
        let hash = this.pinMsg.hash
        let index = this.group.chatList.findIndex(item => item.hash === hash)
        if (index >= 0) {
          let node = this.$refs.msgWrap.querySelectorAll('.msg-item').item(index)
          scrollMsgIntoView(this.$refs.scrollWrap, node.offsetTop - (this.pinMsg ? 40 : 10), node)
        }
      }
      // 防止加载更多
      this.isScrollToView = true
      setTimeout(() => {
        this.isScrollToView = false
      }, 2000)
    },
    scrollToMsg (index) {
      let hash = this.atList[index].hash
      let eleIndex = this.group.chatList.findIndex(item => item.hash === hash)
      if (eleIndex >= 0) {
        let pinLen = this.group.pinList.length
        let node = this.$refs.msgWrap.querySelectorAll('.msg-item').item(eleIndex + pinLen)
        scrollMsgIntoView(this.$refs.scrollWrap, node.offsetTop - (this.pinMsg ? 40 : 10), node)
      }
      this.clearAtList()
    }
  }
}
</script>

<style lang="scss" scoped>
@import './chatRoom.scss';
</style>
