import { useZocksDispatch, useZocksStore } from '../../app/hooks'
import { selectCurrentMediaDeviceId } from '../../store'
import { setSelectedMediaDevice } from '../../store/mediaDevice/mediaDeviceSlice'
import { useCallback, useEffect, useState } from 'react'
import { MediaDeviceManager } from '@zocks-communications/client-sdk-js'

export const useSelectMediaDevice = (deviceKind: MediaDeviceKind) => {
  const dispatch = useZocksDispatch()
  const selectedMediaDeviceId = useZocksStore((state) => selectCurrentMediaDeviceId(state, deviceKind))

  const selectMediaDevice = useCallback(
    (deviceId: string | null) => dispatch(setSelectedMediaDevice({ kind: deviceKind, deviceId })),
    [dispatch, deviceKind]
  )

  return {
    selectedMediaDeviceId,
    selectMediaDevice,
  }
}

export const useSelectMediaDevices = (
  deviceKind: MediaDeviceKind,
  onDeviceSelected: (deviceId: MediaDeviceInfo) => void
) => {
  const { selectedMediaDeviceId, selectMediaDevice } = useSelectMediaDevice(deviceKind)

  const [sources, setSources] = useState<MediaDeviceInfo[]>()

  const listDevices = useCallback(async () => {
    const devices = await MediaDeviceManager.getDevices(deviceKind)
    setSources(devices)
    return devices
  }, [deviceKind])

  useEffect(() => {
    if (!sources) {
      return
    }
    if (!sources.length) {
      selectMediaDevice(null)
    } else if (!selectedMediaDeviceId) {
      const defaultDevice = sources[0]
      selectMediaDevice(defaultDevice.deviceId)
    } else if (!sources.some((d) => d.deviceId === selectedMediaDeviceId)) {
      const defaultDevice = sources[0]
      selectMediaDevice(defaultDevice.deviceId)
      onDeviceSelected(defaultDevice)
    }
  }, [selectMediaDevice, selectedMediaDeviceId, sources, deviceKind, onDeviceSelected])

  useEffect(() => {
    listDevices()
    navigator.mediaDevices.addEventListener('devicechange', listDevices)

    return () => {
      navigator.mediaDevices.removeEventListener('devicechange', listDevices)
    }
  }, [listDevices])

  return {
    selectedMediaDeviceId,
    selectMediaDevice,
    sources,
  }
}
