<script lang="ts">
  import cx from "classnames"
  import {loadProfile, displayProfileByPubkey} from "@welshman/app"
  import Volume from "@assets/icons/volume.svg?dataurl"
  import Icon from "@lib/components/Icon.svelte"
  import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
  import {isMobileViewport} from "@lib/html"
  import ProfileCircle from "@app/components/ProfileCircle.svelte"
  import RoomName from "@app/components/RoomName.svelte"
  import {errorMessage} from "@lib/util"
  import {pushToast} from "@app/util/toast"
  import {
    deriveVoiceParticipants,
    joinVoiceRoom,
    leaveVoiceRoom,
    currentVoiceSession,
    speakingPubkeys,
  } from "@app/voice"

  interface Props {
    url: string
    h: string
  }

  const {url, h}: Props = $props()

  const participants = deriveVoiceParticipants(url, h)
  const isActive = $derived($currentVoiceSession?.url === url && $currentVoiceSession?.h === h)
  let isJoining = $state(false)
  let joinAbortController: AbortController | undefined

  const handleClick = async () => {
    if (isMobileViewport()) {
      pushToast({theme: "error", message: "Voice rooms are not yet supported on mobile."})
      return
    }
    if (isActive) {
      await leaveVoiceRoom()
      return
    }
    if (isJoining) {
      joinAbortController?.abort()
      return
    }
    joinAbortController = new AbortController()
    isJoining = true
    try {
      await joinVoiceRoom(url, h, joinAbortController.signal)
    } catch (e) {
      pushToast({theme: "error", message: `Failed to join voice room: ${errorMessage(e)}`})
    } finally {
      isJoining = false
      joinAbortController = undefined
    }
  }

  $effect(() => {
    for (const pk of $participants) {
      loadProfile(pk)
    }
  })
</script>

<div>
  <SecondaryNavItem onclick={handleClick} class={isActive ? "!bg-base-100 !text-base-content" : ""}>
    {#if isJoining}
      <span class="loading loading-spinner loading-sm"></span>
    {:else}
      <Icon icon={Volume} size={4} class="opacity-70" />
    {/if}
    <RoomName {url} {h} />
  </SecondaryNavItem>
  {#if $participants.length > 0}
    <div class="mt-2 flex flex-col gap-1 pb-1 pl-10">
      {#each $participants as pk (pk)}
        <div class="flex items-center gap-2">
          <div
            class={cx(
              "inline-flex shrink-0 items-center justify-center rounded-full transition-shadow",
              isActive && $speakingPubkeys.has(pk) && "ring-2 ring-success",
            )}>
            <ProfileCircle pubkey={pk} size={5} class="h-5 w-5" />
          </div>
          <span class="ellipsize text-xs opacity-70">
            {displayProfileByPubkey(pk)}
          </span>
        </div>
      {/each}
    </div>
  {/if}
</div>
