<script lang="ts">
  import cx from "classnames"
  import {goto} from "$app/navigation"
  import {Profiles} from "@welshman/app"
  import {app} from "@app/welshman"
  import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
  import ProfileCircle from "@app/components/ProfileCircle.svelte"
  import ProfileCircles from "@app/components/ProfileCircles.svelte"
  import RoomImage from "@app/components/RoomImage.svelte"
  import RoomName from "@app/components/RoomName.svelte"
  import {makeRoomPath} from "@app/routes"
  import {pushModal} from "@app/modal"
  import VoiceRoomJoinDialog from "@app/components/VoiceRoomJoinDialog.svelte"
  import VoiceParticipantMediaBadges from "@app/components/VoiceParticipantMediaBadges.svelte"
  import {makeRoomId} from "@app/groups"
  import {
    VoiceState,
    currentVoiceRoom,
    isParticipantSpeaking,
    mediaStateByIdentity,
    participantKey,
    voiceState,
    type VoiceParticipant,
  } from "@app/call/stores"
  import {
    cancelJoinVoiceRoom,
    deriveVoiceParticipants,
    loadVoiceParticipants,
  } from "@app/call/voice"

  interface Props {
    url: string
    h: string
    replaceState?: boolean
    notification?: boolean
  }

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

  const participants = deriveVoiceParticipants(url, h)
  const participantPubkeys = $derived($participants.flatMap(p => (p.pubkey ? [p.pubkey] : [])))
  const isActive = $derived(
    $voiceState === VoiceState.Connected && $currentVoiceRoom?.id === makeRoomId(url, h),
  )
  const isJoining = $derived(
    $voiceState === VoiceState.Joining && $currentVoiceRoom?.id === makeRoomId(url, h),
  )

  const handleClick = async (e: MouseEvent) => {
    if (isActive) return

    if (isJoining) {
      e.preventDefault()
      cancelJoinVoiceRoom()
      return
    }

    e.preventDefault()
    await goto(makeRoomPath(url, h), {replaceState})
    pushModal(VoiceRoomJoinDialog, {url, h})
  }

  $effect(() => {
    void loadVoiceParticipants(url, h)
  })

  $effect(() => {
    for (const p of $participants) {
      if (p.pubkey) app.use(Profiles).load(p.pubkey)
    }
  })
</script>

<SecondaryNavItem
  href={makeRoomPath(url, h)}
  {replaceState}
  {notification}
  onclick={handleClick}
  class={cx("items-start!", isActive && "bg-base-100! text-base-content!")}>
  <div class="flex w-full min-w-0 flex-col gap-2">
    <div class="flex gap-2 items-center">
      {#if isJoining}
        <span class="loading loading-spinner loading-sm"></span>
      {:else}
        <RoomImage {url} {h} size={4} />
      {/if}
      <RoomName {url} {h} />
    </div>
    {#if participantPubkeys.length > 0}
      {#if isActive}
        {#each $participants as p (participantKey(p as VoiceParticipant))}
          {@const media = $mediaStateByIdentity(p.identity)}
          <div class="flex items-center gap-2 ml-6">
            <div
              class={cx(
                "inline-flex shrink-0 items-center justify-center rounded-full transition-shadow",
                $isParticipantSpeaking(p) && "ring-2 ring-success",
              )}>
              <ProfileCircle pubkey={p.pubkey} size={5} class="h-5 w-5" />
            </div>
            <span class="ellipsize min-w-0 flex-1 text-xs opacity-70">
              {p.pubkey ? app.use(Profiles).display(p.pubkey).get() : "Unknown"}
            </span>
            <VoiceParticipantMediaBadges
              muted={media.muted}
              cameraOn={media.cameraOn}
              size={3}
              class="shrink-0" />
          </div>
        {/each}
      {:else}
        <div class="ml-6">
          <ProfileCircles pubkeys={participantPubkeys} size={5} limit={3} />
        </div>
      {/if}
    {/if}
  </div>
</SecondaryNavItem>
