<template>
  <div class="Mall4j navbar">
    <div class="navbar-content">
      <!-- 1.左边部分 -->
      <div class="left-menu">
        <img
          v-if="webConfig.bsTopBarIcon"
          style="height: 18px;width:59px;margin-right: 10px"
          :src="addDomain(webConfig.bsTopBarIcon)"
          @error="webConfig.bsTopBarIcon=''"
        >
        <img
          v-else
          style="height: 18px;width:59px;margin-right: 10px"
          :src="addDomain(webConfig.bsTopBarIcon)"
        >
        <a
          v-if="(webConfig.bsMenuTitleOpenCn || webConfig.bsMenuTitleCloseCn) || (webConfig.bsMenuTitleOpenEn || webConfig.bsMenuTitleCloseEn)"
          class="site-navbar__brand-lg"
          style="text-transform:none;"
          href="javascript:"
        >{{ sidebar.opened ? webConfig.bsMenuTitleOpenCn : webConfig.bsMenuTitleCloseCn }}</a>
        <a
          v-else
          class="site-navbar__brand-lg"
          style="text-transform:none;"
          href="javascript:"
        >{{ $t('version') + '  ' + $t('side') }}</a>
        <div
          v-if="route.path!=='/multishop/shop-process'"
          class="shrink"
        >
          <svg-icon
            icon-class="icon-zhedie"
            @click="toggleSideBar"
          />
        </div>
      </div>

      <!-- 2.右边部分 -->
      <div class="right-menu">
        <div
          v-if="isShowAnnouncement && isImbox"
          class="news-box"
          style="width:87px;height:100%"
          @click="openUrl"
        >
          <svg-icon
            :class="showHidden ? 'show' : 'hidden'"
            class="message"
            icon-class="message"
          />
          <i
            v-if="message"
            :class="showHidden ? 'show' : 'hidden'"
            class="message-radio"
          />
          客服
        </div>
        <el-dropdown
          class="avatar-container"
          trigger="hover"
        >
          <div class="avatar-wrapper">
            <div class="user-name">
              {{ name || userName }}
            </div>
          </div>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item
                v-if="isShowAnnouncement"
                @click="changePassword"
              >
                <span style="display: block">修改密码</span>
              </el-dropdown-item>
              <el-dropdown-item @click="logout">
                <span style="display: block">{{ $t("navbar.logOut") }}</span>
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
    <!-- 弹窗, 修改密码 -->
    <update-password
      v-if="updatePasswordVisible"
      ref="updatePasswordRef"
    />
  </div>
</template>

<script setup>
import UpdatePassword from '@/components/update-password/index.vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Base64 } from 'js-base64'

const updatePasswordVisible = ref(false)
const webConfigStore = useWebConfigStore()
const webConfig = computed(() => webConfigStore.webConfig)

const appStore = useAppStore()
const sidebar = computed(() => appStore.sidebar)

const userStore = useUserStore()
const name = computed(() => userStore.name)
const userName = computed(() => userStore.userName)
const isShowAnnouncement = computed(() => userStore.isPassShop)

const isImbox = computed(() => {
  const roles = userStore.roles
  const isAdmin = userStore.isAdmin
  const index = roles.findIndex(item => item === 'shop:message:view')
  return isAdmin || index > -1
})

const toggleSideBar = () => {
  if (sessionStorage.getItem('cloudIsExpand') === '0' && !sidebar.value.opened) {
    return
  }
  appStore.toggleSideBar()
}

const route = useRoute()
const router = useRouter()
const logout = async () => {
  ElMessageBox.confirm('确认退出登录吗？', $t('table.tips'), {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    await userStore.logout()
    lockReconnect = true // 退出登录不在重连
    imSocketTask?.close() // 关闭ws
    imSocketTask = null
    localStorage.setItem('cloudMulChatWs', Date.now()) // 通知新窗口关闭ws
    await router.push(`/login?redirect=${route.fullPath}`)
  })
}

const updatePasswordRef = ref(null)
const changePassword = () => {
  updatePasswordVisible.value = true
  nextTick(() => {
    updatePasswordRef.value?.init()
  })
}

/**
 * 开启webstocket
 */
let imSocketTask = {}
const ortherUser = ref(false)
const noAccountable = ref(false)
const newMessage = ref(false)
const notificationDebounce = ref(1)
const messageReminding = ref(null)
const message = ref(0)
const tenantId = computed(() => userStore.tenantId)
const userId = computed(() => userStore.userId)
const notification = ref(false)
// 图标提醒标题闪烁
const showHidden = ref(true)
const openWs = () => {
  try {
    imSocketTask = new WebSocket(
      import.meta.env.VITE_APP_WEBSOCKET_URL + '/tmerclub_im/m/ua/im/websocket/online/' + Base64.encode(getToken()) + '/' + tenantId.value + '/' + userId.value
    )
    const heartCheck = {
      timeout: 19000, // 19s发一次心跳，比server端设置的连接时间稍微小一点，在接近断开的情况下以通信的方式去重置连接时间。 尽量一个小时发送三次
      serverTimeoutObj: null,
      reset () {
        clearTimeout(this.serverTimeoutObj)
        return this
      },
      start () {
        this.serverTimeoutObj = setTimeout(() => {
          if (!imSocketTask) {
            return
          }
          if (imSocketTask.readyState === 1) {
            imSocketTask.send(
              JSON.stringify({
                content: 'HEART_BEAT',
                msgType: 0
              })
            )
            heartCheck.reset().start() // 如果获取到消息，说明连接是正常的，重置心跳检测
          } else {
            // eslint-disable-next-line no-console
            console.log('断线了~~~')
            imSocketTask.close()
            imSocketTask = null
            lockReconnect = false
            onReconnect()
          }
        }, this.timeout)
      }
    }
    imSocketTask.onopen = () => {
      heartCheck.reset().start() // 成功建立连接后，重置心跳检测
      ortherUser.value = false
      imSocketTask.send(
        JSON.stringify({
          content: 'HEART_BEAT',
          msgType: 0
        })
      )
    }

    imSocketTask.onmessage = res => {
      heartCheck.reset().start() // 成功建立连接后，重置心跳检测
      const result = JSON.parse(res.data)
      if (result.code === 10) {
        return
      }
      if (result.code === 11) {
        return
      }
      if (result.code === 12) {
        return
      }
      if (result.code === 15) {
        ElMessage.error($t('chat.notYourResponsibility'))
        noAccountable.value = false
        return false
      }
      if (result.code === '00000' && result.data) {
        message.value = 1
        if (
          result.data.newMessage &&
          notificationDebounce.value &&
          !localStorage.getItem('cloudShop')
        ) {
          notificationDebounce.value = null // 防止连续发送的消息导致右下方弹窗不断
          popNotice($t('chat.notification'), $t('chat.haveANewUnreadMessage')) // 启用通知
        }
        newMessage.value = true
        clearInterval(messageReminding.value)
        if (notification.value) {
          showMessage()
        }
        messageRemindingFn()
      }
    }
    imSocketTask.onerror = () => {
      onReconnect()
    }
  } catch (err) {
    // eslint-disable-next-line no-console
    console.error('创建ws连接失败', err)
  }
}

let lockReconnect = false
const onReconnect = () => {
  if (lockReconnect) return
  lockReconnect = true
  setTimeout(() => {
    // eslint-disable-next-line no-console
    console.log('重新连接')
    // 没连接上会一直重连，设置延迟避免请求过多
    openWs()
    lockReconnect = false
  }, 2000)
}

const openUrl = () => {
  const path = router.resolve({ path: '/im-box' })
  const win = window.open(path.href, 'view_window', 'noopener,noreferrer')
  localStorage.removeItem('cloudVsNotificationMessage')
  if (win) win.opener = null
  message.value = null
  showHidden.value = true
  clearInterval(messageReminding.value)
}

// 右下角消息通知
const popNotice = (user, content) => {
  if (Notification.permission === 'granted') {
    const notification = new Notification(user, {
      body: content
    })
    notification.onclick = function () {
      nextTick(() => {
        setTimeout(() => {
          notificationDebounce.value = 1
          localStorage.removeItem('cloudVsNotificationMessage')
          message.value = null
          const path = router.resolve({ path: '/im-box' })
          const win = window.open(path.href, 'view_window', 'noopener,noreferrer')
          if (win) win.opener = null
          // 具体操作
        }, 500)
      })
      // 可直接打开通知notification相关联的tab窗
      window.focus()
      notification.close()
    }
    notification.onshow = function () {
      setTimeout(() => {
        notificationDebounce.value = 1
        notification.close.bind(notification)
      }, 3000)
    }
  }
}

const messageRemindingFn = () => {
  clearInterval(messageReminding.value)
  messageReminding.value = setInterval(() => {
    // 如果没有获取焦点就判断名称是否包含未读消息
    if (newMessage.value) {
      // 如果包含就显示为空
      showHidden.value = false
      newMessage.value = false
    } else {
      // 否则显示未读消息，间隔0.5秒实现闪烁
      showHidden.value = true
      newMessage.value = true
    }
  }, 500)
}

const showMessage = Debounce(function () {
  ElMessage({
    message: '您有新的未读消息',
    offset: 10,
    duration: 1500
  })
}, 1800)

onMounted(() => {
  message.value = localStorage.getItem('cloudVsNotificationMessage') || null
  if (isShowAnnouncement.value && isImbox.value) {
    openWs()
  }
})
</script>

<style lang="scss" scoped>
.navbar {
  top: 0;
  z-index: 1000;
  position: fixed;
  display: flex;
  align-items: center;
  min-width: 1260px;
  width: 100%;
  height: 50px;
  background: #fff;
  overflow: hidden;
  border-bottom: 1px solid #EBEDF0;
  box-sizing: border-box;

  .navbar-content {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0 20px;
    margin: 0 auto;

    // 1.左边部分
    .left-menu {
      display: flex;
      align-items: center;
    }

    // 2.右边部分
    .right-menu {
      display: flex;
      align-items: center;
      margin-left: auto;
      .avatar-container {
        .avatar-wrapper {
          outline: none;
          cursor: pointer;
        }
      }
      .news-box {
        cursor: pointer;
        font-size: 14px;
        position: relative;
        color: #606266;
        .message {
          color: #155bd4;
          margin-right: 8px;
          font-size: 18px;
        }
        .message-radio {
          border-radius: 50%;
          width: 5px;
          height: 5px;
          background-color: red;
          display: inline-block;
          position: absolute;
          top: 0;
          left: 12px;
        }
        .show {
          visibility: inherit;
        }
        .hidden{
          visibility: hidden;
        }
      }
    }
  }

  .site-navbar__brand-lg {
    margin: 0 auto;
    word-break: break-all;
    /* 按字符截断换行 支持IE和chrome，FF不支持*/
    word-wrap: break-word;
    /* 按英文单词整体截断换行  以上三个浏览器均支持 */
    color: #333333;
    font-weight: bold;
    font-size: 16px;
  }

  .shrink {
    cursor: pointer;
    margin-left: 23px;
    font-size: 18px;
  }

  .navbar-notice img {
    vertical-align: middle;
    width: 20px;
    height: 20px;
    margin: 8px;
  }

}
</style>
