import { useWebSocket } from '@vueuse/core'
import { userStore, globalStore, urgeStore } from '@/stores'
import type { UseWebSocketReturn } from '@vueuse/core'
import { getSN, $XXL, sys_type, sys_type_study_machine, isNotStudyMachine } from '@/utils'
import { useLog, LogType, useTips } from '@/hooks'
import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'

let SOCKET: UseWebSocketReturn<any>

enum SOCKET_MSG_TYPE {
  lockScreen = 'lockScreen',
  unLockScreen = 'unLockScreen',
  desktopPreview = 'desktopPreview',
  inspectorTalkMessage = 'inspectorTalkMessage',
  inspectorStart = 'inspectorStart',
  inspectorEnd = 'inspectorEnd',
  systemMessage = 'systemMessage',
  messageReceive = 'messageReceive',
}

const inspectorEnd = ref<anyObj>()
const inspectorMessage = ref<anyObj>()

export const useSocket = () => {
  const router = useRouter()
  const { token, userInfo } = storeToRefs(userStore())
  const { system } = storeToRefs(globalStore())
  const { getInspectorInfo } = urgeStore()
  const SN = getSN()

  const init = () => {
    return
    if (import.meta.env.MODE === 'test') return
    if (!token.value) return
    stop()
    SOCKET = useWebSocket(
      `${import.meta.env.VITE_WS_URL}?accessToken=${token.value.replace('Bearer ', '')}`,
      {
        autoReconnect: {
          retries: () => true,
          delay: 10000,
          onFailed() {
            console.log('重新连接失败')
          },
        },
        heartbeat: {
          message: '{"type":"ping"}',
          interval: 55000,
          pongTimeout: 3000,
        },
        onConnected,
        onDisconnected,
        onError,
        onMessage,
      },
    )
    SOCKET.send(
      JSON.stringify({
        type: 'ping',
      }),
    )
  }

  const onConnected = (ws: WebSocket) => {
    // ws.binaryType = 'arraybuffer';
    // console.log('ws已连接');
  }

  const onDisconnected = (ws: WebSocket, event: CloseEvent) => {
    if (!token.value) {
      stop()
      SOCKET = null as any
    }
    // console.log('ws已关闭', event);
  }

  const onError = (ws: WebSocket, event: Event) => {
    // console.log(ws, event);
  }

  const onMessage = (ws: WebSocket, event: MessageEvent) => {
    const data = JSON.parse(event.data)

    // 确认接收
    sendMsg({
      type: SOCKET_MSG_TYPE.messageReceive,
      msg: data.msg,
    })

    // 全局消息提醒
    if (data.type === SOCKET_MSG_TYPE.systemMessage) {
      useTips({
        tips: data.msg,
        showCancel: false,
      })
      return
    }

    // if (isWeb) return;
    switch (data.type) {
      case SOCKET_MSG_TYPE.lockScreen:
        if (isNotStudyMachine) return
        // 执行锁屏
        system.value.isLock = true
        useLog(LogType.LockScreenTime, {
          simSerialNumber: SN,
          lockFlag: 1,
        })
        break
      case SOCKET_MSG_TYPE.unLockScreen:
        if (isNotStudyMachine) return
        // 执行解锁
        system.value.isLock = false
        useLog(LogType.LockScreenTime, {
          simSerialNumber: SN,
          lockFlag: 0,
        })
        break
      case SOCKET_MSG_TYPE.desktopPreview:
        if (isNotStudyMachine) return
        onDesktopPreview()
        break
      case SOCKET_MSG_TYPE.inspectorStart:
        // 开始督学
        // console.log('开始督学');
        getInspectorInfo()
          .then(() => router.push('/urge/learning'))
          .catch(() => {
            const _router = useRouter()
            _router.push('/urge/learning')
          }) // 更新督学信息
        break
      case SOCKET_MSG_TYPE.inspectorEnd:
        // 结束督学
        // console.log('结束督学');
        inspectorEnd.value = data.msg
        getInspectorInfo()
          .then(() => router.push('/'))
          .catch(() => {
            const _router = useRouter()
            _router.push('/')
          }) // 更新督学信息
        break
      case SOCKET_MSG_TYPE.inspectorTalkMessage:
        inspectorMessage.value = data.msg
        break
    }
  }

  // 桌面预览
  const onDesktopPreview = async () => {
    try {
      const { data: filePath } = $XXL.getScreenshot()
      // console.log('截图本地地址', filePath);
      if (!filePath)
        return sendMsg({
          type: 'desktopScreenshotImage',
          userId: userInfo.value.userId,
          simSerialNumber: SN,
          msg: '',
        })
      const res = await $XXL.uploadFile({
        url: `${import.meta.env.VITE_SERVER_URL}/sysFileInfo/tenUploadAll`,
        header: {
          Authorization: token,
        },
        filePath,
        fileKey: 'file',
      })
      sendMsg({
        type: 'desktopScreenshotImage',
        userId: userInfo.value.userId,
        simSerialNumber: SN,
        msg: res.url,
      })
    } catch (err) {
      console.log(err)
    }
  }

  // 发送消息
  const sendMsg = (data: anyObj, config = {}) => {
    if (!SOCKET) {
      // console.error('ws不存在');
      return
    }
    SOCKET.send(JSON.stringify(data))
  }

  const textToBuffer = (str: string) => {
    return new TextEncoder().encode(str)
  }

  const bufferToText = (buffer: ArrayBuffer) => {
    return new TextDecoder().decode(buffer)
  }

  const stop = () => {
    SOCKET?.close()
  }

  return {
    init,
    stop,
    sendMsg,
    inspectorEnd,
    inspectorMessage,
  }
}
