import api from '@/api'
import { getLanguage, getUserOpt, setUserOpt } from '@/util/util'
import { mapState } from 'vuex'
import _ from 'lodash'

// 搜索mixin
export const searchUserMixin = {
  data () {
    return {
      isSearch: false, // 搜索展示
      searchList: null // 搜索结果
    }
  },
  methods: {
    searchUser (e, originList) {
      let val = e.target.value.toLocaleLowerCase()
      if (!val) {
        this.isSearch = false
        return
      }

      this.searchList = originList.filter(item => {
        let inName, inNick
        let name = (item.name || item.user_name || '').toLocaleLowerCase()
        let nickName = (item.nick_name || '').toLocaleLowerCase()

        inName = name ? name.indexOf(val) > -1 : false
        inNick = nickName ? nickName.indexOf(val) > -1 : false
        return inName || inNick
      })

      this.isSearch = true
    }
  }
}

// 群搜索mixin
export const searchGroupUserMixin = {
  data () {
    return {
      isSearchGroup: false,
      searchUserTimer: null
    }
  },
  methods: {
    async searchUser (e, originList) {
      clearTimeout(this.searchUserTimer)
      this.searchUserTimer = setTimeout(async () => {
        let val = e.target.value.toLocaleLowerCase()
        let inviteType = this.inviteType
        this.isSearchGroup = true

        if (!val.trim()) {
          originList.forEach(item => {
            this.$set(item, 'isShow', true)
          })
          this.$nextTick(() => {
            this.isSearchGroup = false
            this.showNum = originList.length
          })
          return
        }

        // 当前数据搜索
        originList.forEach(item => {
          let inName, inNick
          let name = (item.user_name || '').toLocaleLowerCase()
          let nickName = (item.nick_name || '').toLocaleLowerCase()

          inName = name ? name.indexOf(val) > -1 : false
          inNick = nickName ? nickName.indexOf(val) > -1 : false

          this.$set(item, 'isShow', inName || inNick)
        })

        // 接口搜索
        if (!(originList.length + 1 >= this.membersNum || inviteType == 1 || inviteType == 2)) {
          await api.group.searchMember({
            group_id: this.group.groupId,
            keyword: val
          }).then(({ data }) => {
            let list = data.data

            list.forEach(item => {
              item.isChecked = false
              item.isChoosed = false
              item.isShow = true
            })

            originList = _.unionBy([...originList, ...list], 'user_id')
          })
        }

        this.$nextTick(() => {
          this.isSearchGroup = false
          this.showNum = originList.filter(item => {
            return item.isShow
          }).length
        })
      }, 200)
    }
  }
}

// @人
export const chatAtMixin = {
  data () {
    return {
      atInd: 0 // @人索引
    }
  },
  methods: {
    atPerson (name, nickName = name) {
      let el = this.$refs.chatInput
      let selectionStart = el.selectionStart
      let realStart = selectionStart - this.keyAfterAt.length
      this.inputMsg = this.inputMsg.slice(0, realStart) + `${name} ` + this.inputMsg.slice(selectionStart)
      this.atInd = 0
      el.focus()
      this.$nextTick(() => {
        el.setSelectionRange(realStart + name.length + 1, realStart + name.length + 1)
      })

      this.$store.commit('updateIsNewAt', {
        isNewAt: this.group.isNewAt,
        isNewAtFound: true
      })
      this.$store.commit('updateGroupSearchList', [])
    },
    handleUp (event) {
      if (this.atInd > 0) {
        this.atInd--
      }

      this.atShow && event.preventDefault()

      return true
    },
    handleDown (event) {
      let membersLen = this.filterMembers.length
      this.atInd < membersLen - 1 ? this.atInd++ : this.atInd = 0
      this.atShow && event.preventDefault()
      return true
    }
  }
}

// 聊天输入框
export const chatInputMixin = {
  data () {
    return {
      selectionAfterAt: false, // 光标在@后面
      keyAfterAt: '', // 光标后的搜索字
      keyAfterAtTimer: '', // 光标后的搜索字触发定时器
      lastKeyAfterAt: '',
      isIOS: !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
      isShowContextmenu: false,
      menuTop: 0, // 右键菜单-top
      menuLeft: 0 // 右键菜单-left
    }
  },
  mounted () {
  },
  computed: {
    ...mapState([
      'copyText'
    ]),
    filterMembers () {
      if (!this.group.groupId) return []

      let members = this.group.membersArray
      let resArr = []
      if (this.keyAfterAt !== '') {
        resArr = this.group.searchList
      } else {
        for (let k = 0; k < members.length; k++) {
          if (members[k].user_id == this.userId) continue
          resArr.push(members[k])
        }
      }

      return resArr.slice(0, 100)
    },
    atShow () {
      this.atInd = 0
      return this.selectionAfterAt && this.filterMembers.length
    }
  },
  watch: {
    keyAfterAt (val) {
      clearTimeout(this.keyAfterAtTimer)
      this.keyAfterAtTimer = setTimeout(() => {
        this.handleKeyAfterAt(val)
      }, 200)
    },
    inputMsg (val, newval) {
      this.handleSelectionChange()
    }
  },
  methods: {
    handleKeyAfterAt (val) {
      if (!this.group.groupId || val.trim() == '') return
      if (this.group.isNewAtFound) return

      if (this.group.membersArray.length < this.group.membersNum) {
        api.group.searchMember({
          group_id: this.group.groupId,
          keyword: val
        }).then(({ data }) => {
          this.$store.commit('updateGroupSearchList', data.data)
        })
      } else {
        let searchList = this.group.membersArray.filter(item => {
          let inName, inNick

          inName = item.user_name ? item.user_name.indexOf(val) > -1 : false
          inNick = item.nick_name ? item.nick_name.indexOf(val) > -1 : false

          return inName || inNick
        })

        this.$store.commit('updateGroupSearchList', searchList)
      }
    },
    getStrBeforeSelection () {
      let el = this.$refs.chatInput
      if (!el) return ''
      let selectionStart = el.selectionStart
      let prevStr = this.inputMsg.slice(0, selectionStart)
      return prevStr
    },
    getStrAfterSelection () {
      let el = this.$refs.chatInput
      if (!el) return ''
      let selectionStart = el.selectionStart
      let prevStr = this.inputMsg.slice(selectionStart)
      return prevStr
    },
    handleClick () {
      this.isShowContextmenu = false
    },
    handleLeft (event) {
      let el = this.$refs.chatInput
      let selectionStart = el.selectionStart
      if (selectionStart === 0) return true
      let prevStr = this.getStrBeforeSelection()
      let members = this.group.members

      for (let k in members) {
        let name = members[k].user_name
        let reg = new RegExp(`@${name} $`)
        if (reg.test(prevStr)) {
          event.preventDefault()
          el.setSelectionRange(selectionStart - name.length - 2, selectionStart - name.length - 2)
          return true
        }
      }
    },
    handleRight (event) {
      let el = this.$refs.chatInput
      let selectionStart = el.selectionStart
      let afterStr = this.getStrAfterSelection()
      let members = this.group.members

      for (let k in members) {
        let name = members[k].user_name
        let reg = new RegExp(`^@${name} `)
        if (reg.test(afterStr)) {
          event.preventDefault()
          el.setSelectionRange(selectionStart + name.length + 2, selectionStart + name.length + 2)
          return true
        }
      }

      return true
    },
    handleDel (event) {
      let el = this.$refs.chatInput
      let selectionStart = el.selectionStart
      if (selectionStart === 0) return
      let prevStr = this.getStrBeforeSelection()
      let members = this.group.members

      for (let k in members) {
        let name = members[k].user_name
        let reg = new RegExp(`@${name} $`)
        if (reg.test(prevStr)) {
          event.preventDefault()
          this.inputMsg = this.inputMsg.slice(0, selectionStart - name.length - 2) + this.inputMsg.slice(selectionStart)
          this.$nextTick(() => {
            el.setSelectionRange(selectionStart - name.length - 2, selectionStart - name.length - 2)
          })
          return
        }
      }
    },
    handleKeyDown (event) {
      if (this.atShow) {
        event.preventDefault()
        let item = this.filterMembers[this.atInd]
        this.atPerson(item.user_name, item.nick_name)
        return
      }

      if (event.altKey || event.ctrlKey) {
        let beforeStr = this.getStrBeforeSelection()
        let afterStr = this.getStrAfterSelection()
        // 单纯换行
        this.inputMsg = beforeStr + '\n' + afterStr
        this.$nextTick(() => {
          this.$refs.chatInput.setSelectionRange(beforeStr.length + 1, beforeStr.length + 1)
        })
      } else {
        this.handleSend(event)
        event.preventDefault()
      }

      return true
    },
    handleFocus () {
      this.$emit('handleFocus') // 针对完整版
      this.updateChatInputFocus(true)
      document.addEventListener('selectionchange', this.handleSelectionChange)
      if (this.isIOS) {
        setTimeout(() => {
          this.$root.$el.addEventListener('click', this.fixIOS)
        }, 0)
      }
    },
    handleBlur () {
      document.removeEventListener('selectionchange', this.handleSelectionChange)
      this.updateChatInputFocus(false)

      // 定时防止@列表/右键粘贴点击前消失
      if (this.selectionAfterAt || this.isShowContextmenu) {
        setTimeout(() => {
          this.selectionAfterAt = false
          this.isShowContextmenu = false
        }, 200)
      }
      if (this.isIOS) {
        let scrollTop = document.body.scrollTop
        document.body.scrollTop = scrollTop
        this.$root.$el.removeEventListener('click', this.fixIOS)
      }
    },
    handleEsc () {
      this.selectionAfterAt = false
    },
    /**
     * 监听光标位置
     */
    handleSelectionChange () {
      let el = this.$refs.chatInput
      if (!el) return
      let selectionStart = el.selectionStart
      let selectionEnd = this.$refs.chatInput.selectionEnd
      if (selectionStart !== selectionEnd) return

      let prevStr = this.getStrBeforeSelection()
      this.selectionAfterAt = /@/.test(prevStr)
      if (this.selectionAfterAt) {
        this.keyAfterAt = prevStr.slice(prevStr.lastIndexOf('@') + 1)
        let isNewAt = this.keyAfterAt.indexOf(this.lastKeyAfterAt) < 0

        this.$store.commit('updateIsNewAt', {
          isNewAt: isNewAt,
          isNewAtFound: isNewAt ? false : this.group.isNewAtFound
        })
        if (isNewAt) this.$store.commit('updateGroupSearchList', [])

        this.lastKeyAfterAt = this.keyAfterAt
      }
    },
    // 监听右键
    handleContextmenu (ev) {
      if (!this.copyText) return

      this.isShowContextmenu = !this.isShowContextmenu

      if (this.isShowContextmenu) {
        this.menuTop = ev.offsetY
        this.menuLeft = ev.offsetX > 100 ? ev.offsetX - 30 : ev.offsetX
      }
    },
    // 监听粘贴
    handlePaste () {
      this.isShowContextmenu = false
      this.inputMsg += this.copyText
    },
    // 关闭emoji面板
    closeEmojiList () {
      this.emojiShow = false
    },
    fixIOS (event) {
      setTimeout(() => {
        if (this.$refs.chatInput === document.activeElement) {
          document.activeElement.blur()
        }
      }, 0)
    }
  }
}

//
export const addPanelSessionMixin = {
  methods: {
    addPanelSession (serverId, sessionId) {
      // 先判断serverId有没有在sessionList
      let isInSession = this.sessionList.some(v => {
        return v.session_id == sessionId
      })

      if (!isInSession) {
        // 没有就加入一个会话
        api.user.getOtherInfo({
          target_id: serverId
        }).then(({ data }) => {
          let userInfo = data.data
          let obj = {
            cover_photo: userInfo.cover_photo,
            is_group: '0',
            name: userInfo.nick_name,
            session_id: sessionId,
            unread: 0
          }
          this.$store.commit('addSessionItem', obj)
        })
      }
    }
  }
}

// 切换语言
export const changeLangMixin = {
  data () {
    return {
      curLang: getUserOpt('lang') || getLanguage()
    }
  },
  methods: {
    changeLang () {
      let changeLang = this.curLang == 'en' ? 'zh' : 'en'
      this.$i18n.locale = changeLang
      this.curLang = changeLang
      // localStorage.setItem('lang', changeLang)
      setUserOpt('lang', changeLang)
    }
  }
}
