import type { ChadClient, UpdatedClient } from '#shared/types'
import { createGlobalState } from '@vueuse/core'

export const useClients = createGlobalState(() => {
  const auth = useAuth()
  const signaling = useSignaling()
  const { emit } = useEventBus()

  const clients = shallowRef<ChadClient[]>([])

  const me = computed(() => clients.value.find(client => client.userId === auth.me.value?.id))

  watch(signaling.socket, (socket) => {
    if (!socket)
      return

    socket.on('clientChanged', (clientId: ChadClient['socketId'], updatedClient: UpdatedClient) => {
      const client = getClient(clientId)

      if (!client)
        return

      updateClient(clientId, updatedClient)

      emit('client:updated', {
        socketId: clientId,
        oldClient: client,
        updatedClient,
      })
    })

    socket.on('disconnect', () => {
      clients.value = []
    })
  })

  function getClient(clientId: ChadClient['socketId']) {
    return clients.value.find(client => client.socketId === clientId)
  }

  function addClient(...client: ChadClient[]) {
    clients.value.push(...client)

    triggerRef(clients)
  }

  function removeClient(clientId: ChadClient['socketId']) {
    clients.value = clients.value.filter(client => client.socketId !== clientId)
  }

  function updateClient(clientId: ChadClient['socketId'], updatedClient: UpdatedClient) {
    const clientIdx = clients.value.findIndex(client => client.socketId === clientId)

    if (clientIdx === -1)
      return

    clients.value[clientIdx] = {
      ...clients.value[clientIdx],
      ...updatedClient,
    } as ChadClient

    triggerRef(clients)
  }

  return {
    me,
    clients,
    getClient,
    addClient,
    removeClient,
    updateClient,
  }
})
