<template>
  <div class="shrink-0 h-12 border-b px-3 flex items-center gap-x-2" v-loading.fullscreen.lock="connectionAttempts != 0" :element-loading-text="loadingText">
    <div class="grow flex items-center text-base gap-x-2">
      <div class="text-slate-400 text-xs mt-0.5">{{comeForm}}</div>
      <div>{{ userInfoStore.getUserInfo().username }}</div>
      <div class="text-xs text-slate-400 flex flex-col">
        <div>
          <span>IP {{ userInfoStore.getUserInfo().loginIp }}</span>
          <span></span>
        </div>
        <div>
          <span>用户ID: {{ userInfoStore.getUserInfo().id }}</span>
          <span>, 用户名: {{ userInfoStore.getUserInfo().username }}</span>
        </div>
      </div>
      <div class="text-xs text-slate-600">
        {{ getLastLoginTime(userInfoStore.getUserInfo().loginDate as number) }} 小时前登录
      </div>
    </div>
    <div class="h-7 w-32 rounded flex items-center justify-center cursor-pointer">
      <el-popover placement="bottom" trigger="hover" :width="420">
        <template #reference>
          <SvgIcon name="tag" class="text-indigo-600 w7 h-7 hover:bg-gray-200" show-arrow />
        </template>
        <template #default>
          <div class="grid grid-cols-7 gap-2">
            <el-tag
              effect="plain"
              size="large"
              class="hover:bg-indigo-100 hover:cursor-pointer"
              v-for="item in tagList"
              @click="addTagToUser(item)"
              >{{ item.tagName }}</el-tag
            >
          </div>
        </template>
      </el-popover>
      <el-popover placement="bottom" trigger="click" :width="100">
        <template #reference>
          <SvgIcon name="clipboard-document-list" class="text-indigo-600 w7 h-7 hover:bg-gray-200" />
        </template>
        <template #default>
          <div class="w-full">
            <div>黑名单</div>
            <button
              @click="showBlackListDialog"
              class="w-32 block mt-2 rounded-md bg-indigo-600 px-3 py-2 text-ss font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
              加入黑名单
            </button>
          </div>
        </template>
      </el-popover>
      <el-popover placement="bottom" trigger="click" :width="80">
        <template #reference>
          <SvgIcon name="user-minus" class="text-indigo-600 w7 h-7 hover:bg-gray-200" />
        </template>
        <template #default>
          <div class="w-full">
            <div>确认解绑会话</div>
            <button @click="unbindSession"
              class="w-28 block mt-2 rounded-md bg-indigo-600 px-3 py-2 text-ss font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
              确认
            </button>
          </div>
        </template>
      </el-popover>
    </div>
  </div>
  <ChatContent ref="chatContentRef" @recallMessage="recallMessage"
               @onSendSuccess="onSendSuccess"
               @click="openAudio" v-loading.fullscreen.lock="loading"
               element-loading-text="正在重新连接..."/>
  <ChatFooter @sendMessage="sendMessage" ref="chatFooterRef" />
  <el-dialog v-model="blackListDialogVisible" title="加入黑名单" width="70%" center>
    <span class="text-base"
      >是否确认将用户<span class="text-red-500 font-medium text-lg">
        {{ userInfoStore.getUserInfo().username }} </span
      >加入到黑名单?</span
    >
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="blackListDialogVisible = false">取消</el-button>
        <el-button type="primary" color="rgb(99,102,241)" @click="addBlackList"> 确认 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import ChatContent from './ChatContent.vue'
import ChatFooter from './ChatFooter.vue'
import {onMounted, onUnmounted, ref} from 'vue'
import {ActivationState, Client} from '@stomp/stompjs'
import * as AuthUtils from '@/utils/auth'
import {useUserInfoStore} from '@/stores/counter'
import {createTagRelations, pageTags} from '@/api/tags'
import type {Message, Tag, TagRelation} from '@/types/global'
import {createBlackList} from '@/api/black'
import {unbindSessionByUserId} from "@/api/session";
import {ElMessage} from "element-plus";
import * as AudioUtils from '@/utils/audioUtils'
import {useRouter} from 'vue-router'
import {formatDate} from "@/utils/formatTime";
import StompWorker from '@/worker/stompWorkers?worker'
import SvgIcon from "@/components/SvgIcon.vue";
const stompWorker = new StompWorker()
stompWorker.postMessage("heartbeat")

const comeForm = import.meta.env.VITE_COMPANY_NAME
const emits = defineEmits(['onNewMessage', 'addTagToUser','removeMessage','unbindSession','openAudio'])

const chatContentRef = ref()
const chatFooterRef = ref()
const userInfoStore = useUserInfoStore()
const tagList = ref<TagRelation[]>([])
const blackListDialogVisible = ref(false)
const stompClient = ref()
const isConnected = ref(false)
const loading = ref(false)
const router = useRouter()
const isVisible = ref(document.visibilityState === 'visible')


const handleVisibilityChange = () => {
  isVisible.value = document.visibilityState === 'visible';
  if (isVisible.value) {

  }
}

const server = ref(
  (
    import.meta.env.VITE_BASE_URL +
    '/websocket/message' +
    '?t=' +
    AuthUtils.getAccessToken()
  ).replace('http', 'ws').replace('https', 'wss')
)

const connectionAttempts = ref(0);
const loadingText = ref('')

const initConnect = () => {
  stompClient.value = new Client({
    brokerURL: server.value,
    reconnectDelay: 5000,
    heartbeatIncoming: 5000,
    heartbeatOutgoing: 60000,
    connectHeaders: {
      Authorization: 'Bearer ' + AuthUtils.getAccessToken()
    }
  })
  stompClient.value.activate()
  stompClient.value.onConnect = (frame: any) => {
    connectionAttempts.value = 0
    isConnected.value = true
    loading.value = false
    console.log('Connected: ' + frame)
    // 订阅客户给客服发送的消息主题
    stompClient.value.subscribe('/service/all',onNewMessage)

    // 订阅其他客服发送的消息
    stompClient.value.subscribe('/service/other', onServiceMessage)

    // 订阅客户已读消息
    stompClient.value.subscribe('/service/customer/read', onCustomerRead)

    // 订阅心跳的消息
    stompClient.value.subscribe('/user/queue/heartbeat', (messageOutput:any) => {
      console.log('收到心跳消息', messageOutput)
    })

  }
  stompClient.value.onWebSocketError = (error:any) => {
    console.log('websocket error', error, '错误时间', formatDate(new Date))
    connectionAttempts.value ++;
    if (connectionAttempts.value > 20) {
      console.log('websocket error')
      loading.value = true
      AuthUtils.removeToken()
      router.push('/login')
    }else {
      loadingText.value = '网络错误,正在重新连接...' + connectionAttempts.value
      console.log('尝试第' + connectionAttempts.value + '次重连')
    }
  }

  stompClient.value.onWebSocketClose = (error:any) => {
    isConnected.value = false
    console.log('websocket close',error, '断开时间' , formatDate(new Date()))
  }

  stompClient.value.onChangeState =  (state: ActivationState) => {
    if (state === ActivationState.ACTIVE) {
      isConnected.value = true
    }
    console.log('websocket status = ', state)
  }
}

// 收到客户的消息
const onNewMessage = (messageOutput:any) => {
  console.log('收到客户的消息', messageOutput)
  const body = JSON.parse(messageOutput.body) as Message
  // 调用index.vue 让他去找sidebar
  emits('onNewMessage', body)
  // 触发更新
  chatContentRef.value.addMessage(body)
  if (body.customerId != AuthUtils.getUserId()) {
    document.title = '【有新消息..】.'
    AudioUtils.playAudio()
    onReceivedCustomerMessage(body)
  }
}

// 客服确认收到客户的消息
const onReceivedCustomerMessage = (msg:Message) => {
  console.log('客服确认收到客户的消息', msg)
  stompClient.value.publish({destination: '/app/support/confirm/received', body: JSON.stringify(msg)})
}
// 收到客服的消息
const onServiceMessage = (messageOutput:any) => {
  const body = JSON.parse(messageOutput.body) as Message
  console.log('收到客服的消息', body)
  chatContentRef.value.addServiceMessage(body)
  chatFooterRef.value.onSendSuccess()
}

// 客户已读客服消息
const onCustomerRead = (messageOutput:any) => {
  console.log('客户已读客服消息', messageOutput)
  const body = JSON.parse(messageOutput.body) as Message
  chatContentRef.value.onCustomerRead(body)
}

const disconnect = () => {
  if (stompClient.value) {
    stompClient.value.deactivate()
  }
  isConnected.value = false
}

const sendMessage = (message: Message) => {
  if (isConnected.value) {
    // 发送消息
    console.log('客服发送消息: ', message)
    stompClient.value.publish({ destination: '/app/support/send', body: JSON.stringify(message) })
  }
}

const recallMessage = (message: Message) => {
  if (isConnected.value) {
    // 发送消息
    console.log('客服发送撤回消息请求: ', message)
    stompClient.value.publish({ destination: '/app/support/recall', body: JSON.stringify(message) })
  }
}

const onSendSuccess = () => {
  chatFooterRef.value.onSendSuccess()
}

// 撤回消息

// 点击左侧的菜单切换用户的时候
const onSwitchUser = () => {
  chatContentRef.value.switchUser()
}

// 快捷回复
const setContent = (content: string) => {
  chatFooterRef.value.setContent(content)
}

// 计算最后登录时间现在多少个小时
const getLastLoginTime = (lastLoginTime: number) => {
  const now = new Date()
  const last = new Date(lastLoginTime)
  const diffTime = now.getTime() - last.getTime()
  return Math.floor(diffTime / (24 * 3600 * 1000))
}

// 获取标签
const getTags = () => {
  const params = {
    pageNo: 1,
    pageSize: 100,
  }
  pageTags(params).then((res) => {
    tagList.value = res.list
  })
}

// 给用户添加标签
const addTagToUser = async (tag: Tag) => {
  const userInfo = userInfoStore.getUserInfo()
  const data = {
    memberId: userInfo.id,
    tagId: tag.id,
    id: null,
    tagName: tag.tagName
  }
  data.id = await createTagRelations(data)
  emits('addTagToUser', data)
}

// 加入黑名单
const showBlackListDialog = () => {
  blackListDialogVisible.value = true
}

const addBlackList = async () => {
  const userInfo = userInfoStore.getUserInfo()
  const data = {
    memberId: userInfo.id,
  }
  const res = await createBlackList(data)
  console.log('加入黑名单', res)
  blackListDialogVisible.value = false
}

// 解绑会话
const unbindSession = async () => {
  const userId = userInfoStore.getUserInfo().id
  try {
    await unbindSessionByUserId(userId as number)
    emits('unbindSession', userId)
    ElMessage.success('解绑成功')
  }catch (error) {
    ElMessage.error('解绑失败')
  }
}

// 打开提示音
const openAudio = () => {
  emits('openAudio',true)
}

stompWorker.onmessage = (event) => {
  if (event.data === 'heartbeat') {
    try {
      stompClient.value.publish({ destination: '/app/support/heartbeat', body: 'ping' })
    }catch (error) {
      // 重新连接
      initConnect()
    }
  }
}

defineExpose({
  onSwitchUser,
  setContent,

})

onMounted(() => {
  initConnect()
  getTags()
  document.addEventListener('visibilitychange', handleVisibilityChange)
})

onUnmounted(() => {
  disconnect()
  document.removeEventListener('visibilitychange', handleVisibilityChange)

})
</script>
