import { MessageBox } from 'element-ui'
import TWEEN from '@tweenjs/tween.js'
import twemoji from 'twemoji'
import dayjs from 'dayjs'

const timestampInterval = 1e3 * 60 * 3 // 3分钟的间隔时间
const cryptoKey = 'dqWt6twz6JyEy3EZ'

export function isDev () {
  return /^test|\.webdev2\./.test(window.location.host) || window.location.port !== ''
}

// 错误弹窗
export function showError (msg, title = 'Error') {
  MessageBox.confirm(msg, title, {
    center: true,
    showCancelButton: false,
    showConfirmButton: false,
    callback () {}
  })
}

// 确认操作弹窗
export function confirmPopup (msg, title = '提示') {
  return new Promise((resolve, reject) => {
    MessageBox.confirm(msg, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(() => {
        resolve()
      })
      .catch(() => {})
  })
}

/**
 * 判断系统||浏览器中英文
 * 对于不支持的浏览器 一律默认为 中文
 */
export function getLanguage () {
  var language = (navigator.language || navigator.browserLanguage).toLowerCase()
  var locale = 'zh'
  if (language.indexOf('en') > -1) {
    locale = 'en'
  } else {
    locale = 'zh'
  }
  return locale
}

/**
 * 获取Url上指定参数
 * @param {String} name 参数名
 */
export function getUrlParam (name) {
  var reg = new RegExp('[?&]' + name + '=([^&#?]*)(&|#|$)')
  var r = window.location.href.match(reg)
  return r ? r[1] : null
}

export var Cookie = {
  setCookie (name, value) {
    var Days = 7
    var exp = new Date()
    exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000)
    exp.setTime(exp.getTime() + 60 * 1000)
    if (
      window.location.port === '8080' ||
      /^test-|\.webdev2\./.test(window.location.host)
    ) {
      document.cookie =
        name + '=' + escape(value) + ';expires=' + exp.toGMTString()
    } else {
      document.cookie =
        name +
        '=' +
        escape(value) +
        ';domain=.mee.chat;path=/;expires=' +
        exp.toGMTString()
    }
  },
  getCookie (name) {
    var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
    var arr = document.cookie.match(reg)
    if (arr) {
      return unescape(arr[2])
    } else {
      return null
    }
  },
  delCookie (name) {
    var str1 = name + '=;domain=.mee.chat;path=/'
    str1 += ';expires=' + new Date(0).toGMTString()
    document.cookie = str1

    var str2 = name + '=;path=/'
    str2 += ';expires=' + new Date(0).toGMTString()
    document.cookie = str2
  }
}
/**
 * 获取聊天区域高度
 * @param {String} msg
 */
export function getResizeHeight () {
  let clientHeight = document.documentElement.clientHeight
  let clientWidth = document.documentElement.clientWidth
  let topHeight = 61
  let botHeight = 181
  var chatBoxHeight
  if (clientHeight < 600) {
    chatBoxHeight = 600 - topHeight - botHeight
  }
  if (clientHeight < 800 || clientWidth < 1000) {
    chatBoxHeight = clientHeight - topHeight - botHeight
  } else {
    chatBoxHeight = clientHeight * 0.8 - topHeight - botHeight
  }
  return chatBoxHeight
}

function rc4 (str, key) {
  var s = []
  var j = 0
  var x
  var res = ''
  for (var i = 0; i < 256; i++) {
    s[i] = i
  }
  for (i = 0; i < 256; i++) {
    j = (j + s[i] + key.charCodeAt(i % key.length)) % 256
    x = s[i]
    s[i] = s[j]
    s[j] = x
  }
  i = 0
  j = 0
  for (var y = 0; y < str.length; y++) {
    i = (i + 1) % 256
    j = (j + s[i]) % 256
    x = s[i]
    s[i] = s[j]
    s[j] = x
    res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256])
  }
  return res
}

/**
 * 加密信息
 * @param {String} msg
 */
export function cryptoMsg (msg) {
  let result
  try {
    result = btoa(rc4(encodeURIComponent(msg), cryptoKey))
  } catch {
    return msg
  }
  return result
}

/**
 * 解密信息
 * @param {String} msg
 */
export function decryptoMsg (msg) {
  let result
  try {
    result = decodeURIComponent(rc4(atob(msg), cryptoKey))
  } catch {
    return msg
  }
  return result
}

const linkRule = new RegExp(
  '(https?|ftp|file)://[-a-zA-Z0-9/-_.?#!+%&]+'
)

/**
 * 向数组添加数据
 * @param {Array} data
 */
export function addSomeInArray (data) {
  let lastTime = null
  data.forEach(item => {
    // 添加timeMsg tag
    if (lastTime === null) {
      item.timeMsg = false
    } else {
      item.timeMsg = parseInt(item.timestamp) - lastTime > timestampInterval
    }
    lastTime = parseInt(item.timestamp)

    addLinkItem(item)
  })
}

/**
 * 单个添加timeMsg tag
 * @param {Array} data
 */
export function addTimeMsgInItem (item, arr) {
  if (arr.length === 0) {
    item.timeMsg = true
  } else {
    let lastTime = parseInt(arr[arr.length - 1].timestamp)
    item.timeMsg = parseInt(item.timestamp) - lastTime > timestampInterval
  }
}

/**
 * 判断是否是移动端
 */
export function isMobile () {
  return /Android|webOS|iPhone|iPod|iPad|BlackBerry/i.test(navigator.userAgent)
}

/**
 * 获得meechat版本
 * */
export function getMeechatType () {
  if (location.pathname.indexOf('mini') > -1) {
    return 'mini'
  } else if (isMobile()) {
    return 'h5'
  } else {
    return 'pc'
  }
}

function convertEntity (str) {
  // &colon;&rpar;
  const entityMap = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&apos;'
  }

  return str.replace(/[&<>'"]/g, function (matched) {
    return entityMap[matched]
  })
}

/*
 * 单个添加链接 msg_type = 10
 * @param {Array} data
 */
export function addLinkItem (item) {
  // 先用实体处理
  if (item.msg_type == 0) {
    item.content = convertEntity(item.content)
    if (item.content.match(linkRule)) {
      item.content = item.content.replace(linkRule, a => {
        return `<a href="${a}" class="link text" target="_blank">${a}</a>`
      })
    }

    item.content = twemoji.parse(item.content, {
      callback: function (icon, options) {
        return 'https://w2.meechat.me/emoji/' + icon + '.svg'
      }
    })
  }
}

/**
 * 移除arr2中满足callback的arr1数组元素
 * @param {Array} arr1 [{hash:1}]
 * @param {Array} arr2 [{hash:1},{hash:2}]
 * @result             arr1 => []
 */
export function removeItemIfEixt (arr1, arr2, callback) {
  arr1.forEach((item, index) => {
    if (arr2.some(item2 => callback(item2) == callback(item))) {
      arr1.splice(index, 1)
    }
  })
}

/**
 * 格式化置顶消息
 */
export function formatPinMsg (pinMsg, userId) {
  pinMsg.name = pinMsg.nick_name
  pinMsg.content = decryptoMsg(pinMsg.msg)
  pinMsg.type = pinMsg.from == userId ? 'me' : 'you'
  pinMsg.avatar = pinMsg.cover_photo || ''
  pinMsg.userId = pinMsg.from
}

/**
 * @param {store} state
 * @param {Number} createTime
 */
export function dealErrorMsg (state, createTime) {
  state.chatList.forEach(item => {
    if (item.createTime == createTime) {
      item.fail = true
      item.loading = false
    }
  })
}

/**
 * 如果含有at他人的信息，格式化
 * @param {String} msg @heitan@aben 123
 * @param {Array} members
 * @result => {@start[10,9]end}@heitan@aben 123
 */
export function encryptAtMsg (msg, members) {
  let ats = []

  members.forEach(user => {
    let reg = new RegExp(`@${user.nick_name}`)
    if (reg.test(msg)) {
      ats.push(user.user_id)
    }
  })

  if (ats.length) {
    msg = `{@start[${ats.toString()}]end}${msg}`
  }

  return msg
}

/**
 *
 * @param {String} msg
 * @return {Array|Null}
 */
export function decryptAtMsg (msg) {
  let reg = /^{@start\[(.*)\]end}/
  let ret = reg.exec(msg)
  if (ret) {
    return ret[0].split(',')
  }
}
/**
 *判断是否是at我的信息
 */
export function checkAtMe (msg, username) {
  if (!username) return false
  let reg = new RegExp(`@${username}`)
  return reg.test(msg)
}

export function scrollIntoView (node, offsetTop) {
  let distance = Math.abs(offsetTop - node.scrollTop)
  let time = distance > 500 ? 1000 : distance * 2
  let tw = new TWEEN.Tween(node)
    .to({ scrollTop: offsetTop }, time)
    .easing(TWEEN.Easing.Quadratic.Out)
  return tw.start()
}

export function scrollMsgIntoView (node, offsetTop, targetNode, callback) {
  scrollIntoView(node, offsetTop)
    .onComplete(() => {
      targetNode.classList.toggle('active')
      callback && callback()
    })

  setTimeout(() => {
    targetNode.classList.toggle('active')
  }, 3000)
}

export var noticeManager = {
  tabTimer: null, // tab切换定时器
  askPermission () {
    return new Promise((resolve, reject) => {
      if (!('Notification' in window)) {
        reject(new Error('This browser does not support desktop notification'))
      } else if (Notification.permission === 'granted') {
        resolve()
      } else if (Notification.permission === 'default ') {
        Notification.requestPermission(function (permission) {
          // 如果用户同意，就可以向他们发送通知
          if (permission === 'granted') {
            resolve()
          } else {
            reject(new Error())
          }
        })
      }
    })
  },
  showNotification (data) {
    // 开启全局消息免扰
    if (this.getGlobalNotice() == 1) return

    // 已经打开页面了，就不需要额外通知
    let userId = localStorage.getItem('user_id')
    // 自己发的消息不用通知
    if (userId == data.from) return

    this.askPermission().then(() => {
      let notification = new Notification(data.name, {
        body: '你收到了一条消息',
        icon: `/dist/img/icons/meechat.png`
      })

      // 打开页面
      let path
      if (data.group_id) {
        path = `/group/${data.group_id}`
      } else {
        let sessionId = +data.to > +data.from ? `${data.from}-${data.to}` : `${data.to}-${data.from}`
        path = `/pm/${sessionId}`
      }

      notification.onclick = () => {
        window.$router.push({ path })
        notification.close()
        window.focus()
      }

      setTimeout(() => {
        notification.close()
      }, 3500)
    })
  },
  changeTitle (num) {
    // 开启全局消息免扰
    // if (this.getGlobalNotice() == 1) return
    let title = num ? `${num}条新消息 - MeeChat` : `MeeChat`

    document.title = title

    if (num) {
      num = num > 99 ? '99+' : num
      if (this.tabTimer) clearTimeout(this.tabTimer)
    }
  },
  getGlobalNotice () {
    if (window.Notification && Notification.permission === 'granted') {
      // getUserOpt('mute')
      // let systemConfig = JSON.parse(localStorage.getItem('systemConfig') || '{}')
      // let mute = getUserOpt('mute')
      // return typeof systemConfig.mute === 'undefined' ? 1 : systemConfig.mute
      let mute = getUserOpt('mute')
      return mute || 0
    } else {
      return 1
    }
  },
  /**
   * @des 设置通知提醒
   * @param type {0:开启,1:关闭}
   * */
  setGlobalNotice (type, that) {
    // let systemConfig = JSON.parse(localStorage.getItem('systemConfig') || '{}')
    if (type == 0) {
      Notification.requestPermission(function (permission) {
        // 如果用户同意，就可以向他们发送通知
        let mute = permission === 'granted' ? 0 : 1

        that.openGlobalNotice = mute
        setUserOpt('mute', mute)
      })
    } else {
      that.openGlobalNotice = type
      setUserOpt('mute', type)
    }
  }
}

/**
 * @des 转换消息时间
 * @param {timeStamp} 时间戳
 * @param {type} 类型{1:会话列表,2:信息段}
*/
export function formatMsgTime (timeStamp, type = 1, that) {
  if (!timeStamp) return ''

  let lastDate = dayjs().subtract(1, 'days').format('YYYY-MM-DD') // 昨天
  let inputDay = dayjs(timeStamp * 1)
  let inputDate = inputDay.format('YYYY-MM-DD')

  switch (type) {
    // 会话列表
    case 1:
      if (inputDate < lastDate) {
        return inputDay.format('MM-DD')
      } else if (lastDate == inputDate) {
        return that.$t('chat.yesterday')
      } else {
        return inputDay.format('HH:mm')
      }
    // 信息段
    case 2:
      if (inputDate < lastDate) {
        return inputDay.format('MM-DD HH:mm')
      } else if (lastDate == inputDate) {
        return that.$t('chat.yesterday') + ` ${inputDay.format('HH:mm')}`
      } else {
        return inputDay.format('HH:mm')
      }
  }
}

/**
 * @des 跳去h5登录页
 *  */
export function toLoginPage () {
  let url = encodeURIComponent(location.hash.replace('#', ''))
  location.replace(`${location.origin + location.pathname}#/login?from=${url}`)
  // rounter.replace(`/login?from=${url}`)
}

/**
 * @des 将图片地址转成base64
*/
export function getBase64 (imgUrl, callback) {
  window.URL = window.URL || window.webkitURL
  var xhr = new XMLHttpRequest()
  xhr.open('get', imgUrl, true)
  // 至关重要
  xhr.responseType = 'blob'
  xhr.onload = function () {
    if (this.status == 200) {
      // 得到一个blob对象
      var blob = this.response
      //  至关重要
      let oFileReader = new FileReader()
      oFileReader.onloadend = function (e) {
        let base64 = e.target.result

        callback && callback(base64)
      }
      oFileReader.readAsDataURL(blob)
    }
  }
  xhr.send()
}

/**
 * @des 图片懒加载
 * @param {el} wrap 图片容器
 * @param {HTMLCollection} imageArr 图片列表
 * @param {String} derection 整体列表滑动方向['down','up']
 */
export function lazyloadImage ({ wrap, imageArr, derection = 'down' }) {
  if (!imageArr || imageArr.length <= 0) return
  let imageLen = imageArr.length
  let listScrollTop = wrap.scrollTop
  let listClientHeight = wrap.clientHeight

  switch (derection) {
    case 'down':
      for (let i = 0; i < imageLen; i++) {
        let item = imageArr[i]
        let originUrl = item.getAttribute('originurl')
        let url = item.getAttribute('src')

        if (item.offsetTop - listScrollTop <= listClientHeight) {
          if (originUrl && originUrl != url) item.setAttribute('src', originUrl)
        } else {
          return i >= 1 ? i - 1 : 0
        }
      }
      break
    case 'up':
      for (let i = imageLen - 1; i >= 0; i--) {
        let item = imageArr[i]
        let originUrl = item.getAttribute('originurl')
        let url = item.getAttribute('src')
        let top = item.getBoundingClientRect().top

        if (top >= -100 && top < listClientHeight + 300) {
          if (originUrl && originUrl != url) item.setAttribute('src', originUrl)
        }
      }
      break
  }
}

/**
 * @des 获取头像背景色
 * @param {*} str 房间号
 * @param {*} userId 当前用户id
 */
export function getAvatarBgColor (str, userId) {
  str += ''
  if (str.match('-')) {
    let num = 0
    str.split('-').forEach(e => {
      if (e !== userId) {
        num = e % 9
      }
    })
    return num + ''
  } else {
    return str % 9 + ''
  }
}

/**
 * @des 打开一个空白窗口
 * @param {String} url 链接
 * @param {Number} iWidth 弹出窗口的宽度
 * @param {Number} iHeight 弹出窗口的高度
*/
export function openBlankWindow (url = '', iWidth = 500, iHeight = 600) {
  var iTop = (window.screen.availHeight - 30 - iHeight) / 2 // 获得窗口的垂直位置;
  var iLeft = (window.screen.availWidth - 10 - iWidth) / 2 // 获得窗口的水平位置;
  var winHandler = window.open(url, '_blank', 'height=' + iHeight + ', width=' + iWidth + ', top=' + iTop + ', left=' + iLeft + ', toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no')

  return winHandler
}

/**
 * @des 本地存储用户操作
 * [{'loginType':'登录类型'},{'lang':'语言'}]
 */
export function getUserOpt (key) {
  let userOpt = localStorage.getItem('userOpt') || '{}'
  userOpt = JSON.parse(userOpt)

  return userOpt[key] || ''
}

export function setUserOpt (key, val) {
  let userOpt = localStorage.getItem('userOpt') || '{}'
  userOpt = JSON.parse(userOpt)
  userOpt[key] = val

  localStorage.setItem('userOpt', JSON.stringify(userOpt))
}
