<template>
  <div class="box-ft">
    <transition name="msgbox-fade">
      <Emoji v-show="emojiShow" @addEmoji="addEmoji"></Emoji>
    </transition>
    <chat-at
      ref="chatAt"
      v-if="atShow"
      @atperson="atPerson"
      :curInd="atInd"
      :filterList="filterMembers"
    ></chat-at>
    <div class="toolbar">
      <i class="look-icon" @click.stop="emojiShow = !emojiShow"></i>
      <div class="file-icon">
        <input type="file" ref="inputFile" name="res" @change="handleFile">
      </div>
      <!-- <i class="icon-packet" @click="$packetGet"></i> -->
    </div>
    <div class="send-content">
      <form class="input-wrap" @submit="handleSend">
        <textarea
          @keydown.up.prevent="handleUp"
          @keydown.down.prevent="handleDown"
          cols="1"
          ref="chatInput"
          rows="1"
          @keydown.enter="handleKeyDown"
          placeholder
          v-focus
          v-model="inputMsg"
          @blur="handleBlur"
        />
      </form>
    </div>
    <div class="send-action">Enter发送，Ctrl + Enter 换行
      <el-button @click="handleSend">发送</el-button>
    </div>
  </div>
</template>
<script>
import Emoji from '@/components/emoji'
import chatAt from '@/components/chatAt'
import { Message } from 'element-ui'
import { mapState, mapMutations, mapActions } from 'vuex'
import { chatAtMixin } from '@/mixins'
import ImageMin from '@/util/imageMin.js'
// import editArea from './editArea'

export default {
  name: 'inputArea',
  mixins: [chatAtMixin],
  components: {
    Emoji,
    chatAt
  },
  computed: {
    ...mapState(['group', 'userId']),
    ...mapState({
      chatInputFocus: state => state.group.chatInputFocus,
      blockList: state => state.group.blockList
    }),
    filterMembers () {
      let val = this.inputMsg.replace('@', '')
      let members = this.group.members
      let resArr = []
      for (let k in members) {
        if (k == this.userId) continue
        if (val.indexOf(members[k].user_name) === -1) {
          resArr.push(members[k])
        }
      }
      return resArr
    },
    atShow () {
      return this.inputMsg.match(/@$/) && this.filterMembers.length
    }
  },
  data () {
    return {
      emojiShow: false,
      inputMsg: '',
      atInd: 0
    }
  },
  mounted () {
    document.addEventListener('paste', this.initPaste)
    document.addEventListener('drop', this.initDrop)
    document.addEventListener('dragover', this.initDragOver)
    document.body.addEventListener('click', () => {
      this.emojiShow = false
    })
  },
  beforeDestroy () {
    document.removeEventListener('paste', this.initPaste)
    document.removeEventListener('drop', this.initDrop)
    document.removeEventListener('dragover', this.initDragOver)
  },
  methods: {
    ...mapMutations(['updateChatInputFocus', 'addChatItem']),
    ...mapActions(['doSendMsg', 'doSendFile']),
    addEmoji (val) {
      this.inputMsg += val
      this.emojiShow = false
      this.$refs.chatInput.focus()
    },
    handleKeyDown (event) {
      if (this.atShow) {
        event.preventDefault()
        let item = this.filterMembers[this.atInd]
        this.atPerson(item.user_name)
        return
      }

      if (event.altKey || event.ctrlKey || event.metaKey) {
        // 单纯换行
        this.inputMsg = this.inputMsg + '\n'
      } else {
        event.returnValue = false
        this.handleSend(event)
      }

      return false
    },
    /**
     * @des 处理消息发送
     */
    handleSend (e) {
      // 判断是否被禁言
      if (this.blockList.some(id => id == this.userId)) {
        Message({
          message: '您已被禁言',
          type: 'error'
        })
        return
      }

      let text = this.inputMsg.trim()

      if (text.length === 0) {
        Message({
          message: '聊天内容不能为空',
          type: 'warning'
        })
        return
      }

      let opt = {
        type: 0,
        msg: text
      }

      // 用户不是第一次发言
      if (this.group.members[this.userId]) {
        let createTime = Date.now()
        this.addChatItem({
          from: this.userId,
          content: text,
          hash: `${createTime}`,
          timestamp: createTime,
          createTime,
          msg_type: '0',
          loading: true
        })
        opt.createTime = createTime
      }

      this.doSendMsg(opt)

      // 滚到底部
      this.$nextTick(function () {
        this.inputMsg = ''
        this.$emit('toBottom')
      })

      e.preventDefault()
      return false
    },
    /**
     * 文件预处理
     * @return {Object} data 预处理文件信息
     * @param {Number} data.type
     * @param {File} data.res
     */
    async preHandleFile (file) {
      let type = file.type
      let size = file.size
      if (type.match('video')) {
        return size > 3 * 1024 * 1024
          ? Promise.reject(new Error(file))
          : Promise.resolve({
            type: 2,
            res: file
          })
      } else if (type.match('audio')) {
        return size > 2 * 1024 * 1024
          ? Promise.reject(new Error(file))
          : Promise.resolve({
            type: 3,
            res: file
          })
      } else if (type.match('image')) {
        let image = await new ImageMin({
          file: file,
          maxSize: 1024 * 1024
        })
        return {
          type: 1,
          preview: image.base64,
          res: image.res
        }
      }
    },
    /**
     * @des 处理文件发送
     */
    async handleFile (e) {
      let inputfile
      if (e.constructor === File) {
        inputfile = e
      } else {
        inputfile = e.target.files[0]
      }

      try {
        let fileInfo = await this.preHandleFile(inputfile)
        let opt = { res: fileInfo.res }
        if (this.group.members[this.userId]) {
          let createTime = Date.now()
          this.addChatItem({
            content: fileInfo.preview || '',
            from: this.userId,
            hash: `${createTime}`,
            msg_type: fileInfo.type,
            timestamp: createTime,
            res: fileInfo.res,
            loading: true,
            createTime
          })
          opt.createTime = createTime
        }
        this.doSendFile(opt)
        setTimeout(() => {
          this.$refs.inputFile.value = null
          this.$emit('toBottom')
        }, 100)
      } catch (error) {
        Message({
          message: '上传文件大小限制：音频2M以内，视频3M以内',
          type: 'warning'
        })
      }
    },
    handleBlur () {
      this.updateChatInputFocus(false)
    },
    initDrop (e) {
      e.preventDefault()
      let files = Array.from(e.dataTransfer.files)
      files.forEach(file => this.handleFile(file))
    },
    initDragOver (e) {
      e.preventDefault()
    },
    initPaste (event) {
      var items = (event.clipboardData || window.clipboardData).items
      if (items && items.length) {
        Array.from(items).forEach(item => {
          let file = item.getAsFile()
          if (file) {
            this.handleFile(file)
          }
        })
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.box-ft {
  height: 180px;
  border-top: 1px solid #d6d6d6;
  padding-right: 16px;
  position: relative;
}

.toolbar {
  padding: 10px 20px;
  font-size: 0;
  i {
    color: #333333;
    font-size: 18px;
    margin-right: 15px;
    vertical-align: middle;
    cursor: pointer;
  }
}
.send-action {
  text-align: right;
}
.look-icon {
  background: url("../../assets/icon-face.png") no-repeat;
  background-size: 100%;
  width: 20px;
  height: 20px;
  display: inline-block;
  vertical-align: middle;
  cursor: pointer;
}
.file-icon {
  background: url("../../assets/icon-file.png") no-repeat;
  background-size: 100%;
  width: 19px;
  height: 18px;
  display: inline-block;
  vertical-align: middle;
  position: relative;
  input[type="file"] {
    cursor: pointer;
    opacity: 0;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
  }
}
.emoji-list {
  position: absolute;
  border-radius: 4px;
  border: 1px solid #d6d6d6;
  left: 10px;
  height: 226px;
  top: -236px;
  overflow: auto;
  background-color: #ffffff;
  width: 232px;
}
.send-action {
  color: #bababa;
  font-size: 12px;
  button {
    margin-left: 10px;
  }
}
.input-wrap {
  textarea {
    display: block;
    background-color: #eee;
    width: 100%;
    box-sizing: border-box;
    resize: none;
    height: 90px;
    line-height: 1.4;
    padding-left: 20px;
    outline: none;
    border: 0;
    font-size: 14px;
    margin-bottom: 10px;
  }
}
.icon-packet{
  display: inline-block;
  margin-left: 20px;
  vertical-align: middle;
  background: url('../../assets/icon-packet.png') center center no-repeat;
  background-size: 100%;
  width: 21px;
  height: 21px;
}
</style>
