import type { ShareSettings } from '~/components/ShareScreenDialog.vue'
import { ShareScreenDialog } from '#components'
import { getVersion } from '@tauri-apps/api/app'
import { openUrl as tauriOpenUrl } from '@tauri-apps/plugin-opener'
import { computedAsync, createGlobalState } from '@vueuse/core'
import { useClients } from '~/composables/use-clients'

export const useApp = createGlobalState(() => {
  const { clients } = useClients()
  const mediasoup = useMediasoup()
  const signaling = useSignaling()
  const { emit } = useEventBus()
  const dialog = useDialog()

  const ready = ref(false)
  const isTauri = computed(() => '__TAURI_INTERNALS__' in window)
  const commitSha = __COMMIT_SHA__
  const version = computedAsync(() => {
    if (import.meta.dev) {
      return 'dev'
    }
    else if (isTauri.value) {
      return getVersion()
    }
    else {
      return 'web'
    }
  }, '-')

  const inputMuted = computed(() => {
    return !!mediasoup.micProducer.value?.paused
  })
  const previousInputMuted = ref(inputMuted.value)

  const outputMuted = ref(false)

  const videoEnabled = computed(() => {
    return !!mediasoup.videoProducer.value
  })

  const sharingEnabled = computed(() => {
    return !!mediasoup.shareProducer.value
  })

  const somebodyStreamingVideo = computed(() => {
    return !!mediasoup.videoProducer.value
      || !!mediasoup.shareProducer.value
      || mediasoup.videoConsumers.value.length > 0
      || mediasoup.shareConsumers.value.length > 0
  })

  async function muteInput() {
    if (inputMuted.value || !mediasoup.micProducer.value)
      return

    await mediasoup.pauseProducer(mediasoup.micProducer.value)

    emit('audio:muted')
  }

  async function unmuteInput() {
    if (!inputMuted.value || !mediasoup.micProducer.value)
      return

    if (outputMuted.value) {
      await unmuteOutput()
    }

    await mediasoup.resumeProducer(mediasoup.micProducer.value)

    emit('audio:unmuted')
  }

  async function toggleInput() {
    if (inputMuted.value)
      await unmuteInput()
    else
      await muteInput()
  }

  async function muteOutput() {
    if (outputMuted.value)
      return

    outputMuted.value = true

    previousInputMuted.value = inputMuted.value

    await muteInput()

    await signaling.socket.value?.emitWithAck('updateClient', {
      outputMuted: true,
    })

    emit('output:muted')
  }

  async function unmuteOutput() {
    outputMuted.value = false

    if (!previousInputMuted.value)
      await unmuteInput()

    await signaling.socket.value?.emitWithAck('updateClient', {
      outputMuted: false,
    })

    emit('output:unmuted')
  }

  async function toggleOutput() {
    if (outputMuted.value)
      await unmuteOutput()
    else
      await muteOutput()
  }

  async function toggleVideo() {
    if (!mediasoup.videoProducer.value) {
      await mediasoup.enableVideo()
      emit('video:enabled')
    }
    else {
      await mediasoup.disableProducer(mediasoup.videoProducer.value)
      emit('video:disabled')
    }
  }

  async function toggleShare() {
    if (!mediasoup.shareProducer.value) {
      const { close } = dialog.open(ShareScreenDialog, {
        props: {
          header: 'Share settings',
          modal: true,
          draggable: false,
          closable: false,
          dismissableMask: true,
          style: {
            width: '440px',
          },
        },
        emits: {
          onShare: async (settings: ShareSettings) => {
            await mediasoup.enableShare(settings)
            emit('share:enabled')
            close()
          },
        },
      })
    }
    else {
      await mediasoup.disableProducer(mediasoup.shareProducer.value)
      emit('share:disabled')
    }
  }

  async function openUrl(href: string) {
    if (isTauri.value) {
      await tauriOpenUrl(href)
    }
    else {
      window.open(href, '_blank', 'noopener noreferrer')
    }
  }

  return {
    ready,
    clients,
    inputMuted,
    muteInput,
    unmuteInput,
    toggleInput,
    outputMuted,
    muteOutput,
    unmuteOutput,
    toggleOutput,
    toggleVideo,
    version,
    isTauri,
    commitSha,
    toggleShare,
    videoEnabled,
    sharingEnabled,
    somebodyStreamingVideo,
    openUrl,
  }
})
