import user, { UserRole } from '~/store/user';

export type TSocketRes<T> = {
  content?: T,
  client_name?: string
  client_id?: string
  from_client_id?: string
  from_client_name?: string
  time: string
  to_client_id?: string
  type: string
}

const CLIENT_NAME = `${user.user_id}|${user.user_realname}|${UserRole}`
export function createSocket(
  options: { teacher: string, student: string },
  hooks: {
    message: Function,
    reload?: Function
  }
) {
  const ws: WebSocket & { LastPingTime?: number } = new WebSocket("wss://socket.bozedu.net")
  ws.LastPingTime = Date.now()

  setInterval(() => {
    const now = Date.now()
    console.log(`[SOCKET 心跳检测](${options.teacher}_${options.student}) :`);
    console.log(new Date(now).toLocaleString(), new Date(ws.LastPingTime!).toLocaleString(), `${(now - ws.LastPingTime!) / 1000}s`);

    if (ws.LastPingTime && now - ws.LastPingTime > 15000) {
      console.log(`[SOCKET PONG](${options.teacher}_${options.student}): ${CLIENT_NAME}`);
      // 重新连接
      hooks?.reload?.()
      ws.LastPingTime = Date.now()
    }
  }, 10000);

  ws.addEventListener('message', (e) => {
    if (e.data) {
      try {
        const data: TSocketRes<string> = JSON.parse(e.data)
        if (data.type === 'ping') {
          console.log(`[SOCKET PING](${options.teacher}_${options.student})`);
          ws.LastPingTime = Date.now()
          return
        }
        if (CLIENT_NAME === data.from_client_name) return
        if (!['ping'].includes(data.type)) {
          ws.LastPingTime = Date.now()
          console.groupCollapsed(`[SOCKET ${data.type.toLocaleUpperCase()}](${options.teacher}_${options.student}) ${data.time} : ${data.client_name ?? data.from_client_name}`)
          console.log(data);
        }

        if (data.type === 'login') {

        }

        if (data.type === 'say') {
          const content = {
            ...data,
            content: JSON.parse(decodeURIComponent(data.content!))
          }
          console.log(content);

          hooks.message(content)
        }

      } catch (error) {
        console.error(error);
      } finally {
        console.groupEnd();
      }
    }
  })

  ws.addEventListener('error', (err) => {
    console.error('ws error :>> ', ws, err);
  })

  ws.addEventListener('open', (e) => {
    console.log(`[ws open](${options.teacher}_${options.student})`);
    ws.send(JSON.stringify({
      "type": "login",
      "client_name": CLIENT_NAME,
      "room_id": `aiwen_consult_${options.teacher}_${options.student}`
    }))
  })

  ws.addEventListener('close', (e) => {
    console.log(`[ws close](${options.teacher}_${options.student})`);
  })

  return ws
}

export function socketSend(ws: WebSocket & { LastPingTime?: number }, content: unknown) {
  console.log('socketSend ws : ')
  ws.LastPingTime = Date.now()
  if (ws.readyState === WebSocket.OPEN) {
    // WebSocket 连接已建立
    ws.send(
      JSON.stringify({
        type: "say",
        to_client_id: 'all',
        content: encodeURIComponent(JSON.stringify(content))
      })
    )
  } else {
    ws.onopen = () => {
      ws.send(
        JSON.stringify({
          type: "say",
          to_client_id: 'all',
          content: encodeURIComponent(JSON.stringify(content))
        })
      )
    }
  }

}
