<template>
  <div class="grid grid-cols-[360px_1fr] gap-2 p-2 h-screen grid-rows-[auto_1fr] max-w-full">
    <div
      class="flex items-center justify-between gap-2 rounded-xl p-3 bg-surface-950"
    >
      <div class="inline-flex items-center gap-3">
        <PrimeBadge class="opacity-50" severity="secondary" :value="version" size="small" />
        <PrimeBadge :severity="connected ? 'success' : 'danger' " />
      </div>

      <PrimeButtonGroup class="ml-auto">
        <PrimeButton :severity="inputMuted ? 'info' : undefined" outlined @click="toggleInput">
          <template #icon>
            <Component :is="inputMuted ? MicOff : Mic" />
          </template>
        </PrimeButton>
        <PrimeButton :severity="outputMuted ? 'info' : undefined" outlined @click="toggleOutput">
          <template #icon>
            <Component :is="outputMuted ? VolumeOff : Volume2" />
          </template>
        </PrimeButton>
      </PrimeButtonGroup>

      <PrimeButton :severity="videoEnabled ? 'success' : undefined" outlined @click="toggleVideo">
        <template #icon>
          <Component :is="videoEnabled ? CameraOff : Camera" />
        </template>
      </PrimeButton>

      <PrimeButton :severity="sharingEnabled ? 'success' : undefined" outlined @click="toggleShare">
        <template #icon>
          <Component :is="sharingEnabled ? ScreenShareOff : ScreenShare" />
        </template>
      </PrimeButton>
    </div>

    <div
      class="flex items-center justify-center rounded-xl p-3 bg-surface-950"
    >
      <PrimeSelectButton
        v-model="activeTab"
        :options="tabs"
        option-label="id"
        :allow-empty="false"
        style="--p-togglebutton-content-padding: 0.25rem 0.5rem"
      >
        <template #option="{ option }">
          <Component :is="option.icon" size="24" />
        </template>
      </PrimeSelectButton>
    </div>

    <PrimeScrollPanel class="bg-surface-900 rounded-xl overflow-hidden" style="min-height: 0">
      <div v-auto-animate class="p-3 space-y-1">
        <template v-for="channel in channels" :key="channel.id">
          <PrimeDivider>
            <PrimeButton size="small" variant="text" @click="joinChannel(channel)">
              {{ channel.name }}
            </PrimeButton>
          </PrimeDivider>
          <ClientRow v-for="client in clients.filter(_client => _client.channelId === channel.id)" :key="client.socketId" :client="client">
            {{ client.userId }}
          </ClientRow>
        </template>
        <!--        <ClientRow v-for="client of clients" :key="client.userId" :client="client" /> -->
      </div>
    </PrimeScrollPanel>

    <div class="bg-surface-900 rounded-xl overflow-hidden p-3 flex flex-col min-h-full">
      <dl>
        <dt>Socket ID</dt>
        <dd>{{ socket?.id }}</dd>

        <br>
        <dt>Producers</dt>
        <dd v-for="producer in producersArray" :key="producer.id">
          {{ producer.id }}
          {{ producer.appData }}
        </dd>

        <br>
        <dl>Consumers</dl>
        <dd v-for="consumer in consumersArray" :key="consumer.id">
          {{ consumer.id }}
          {{ consumer.appData }}
        </dd>
      </dl>
      <slot />
    </div>
  </div>

  <FullscreenGallery />
</template>

<script setup lang="ts">
import chadApi from '#shared/chad-api'
import {
  Camera,
  CameraOff,
  MessageCircle,
  Mic,
  MicOff,
  ScreenShare,
  ScreenShareOff,
  Settings,
  TvMinimalPlay,
  UserPen,
  Volume2,
  VolumeOff,
} from 'lucide-vue-next'

const channels = shallowRef<any[]>([])

;(async () => {
  channels.value = await chadApi<any[]>('/channels', { method: 'GET' })
})()

const { me } = useClients()
const {
  version,
  clients,
  inputMuted,
  outputMuted,
  videoEnabled,
  sharingEnabled,
  somebodyStreamingVideo,
  toggleInput,
  toggleOutput,
  toggleVideo,
  toggleShare,
} = useApp()
const { connect, connected, socket } = useSignaling()
const { consumersArray, producersArray } = useMediasoup()

interface Tab {
  id: string
  icon: Component
  onClick: () => void | Promise<void>
}

const route = useRoute()

const tabs = computed<Tab[]>(() => {
  const result = []

  if (somebodyStreamingVideo.value) {
    result.push({
      id: 'Gallery',
      icon: TvMinimalPlay,
      onClick: () => {
        navigateTo({ name: 'Gallery' })
      },
    })
  }

  result.push(
    {
      id: 'Index',
      icon: MessageCircle,
      onClick: () => {
        navigateTo({ name: 'Index' })
      },
    },
    {
      id: 'Profile',
      icon: UserPen,
      onClick: () => {
        navigateTo({ name: 'Profile' })
      },
    },
    {
      id: 'Preferences',
      icon: Settings,
      onClick: () => {
        navigateTo({ name: 'Preferences' })
      },
    },
  )

  return result
})

const activeTab = ref<Tab>(tabs.value.find(tab => tab.id === route.name) ?? tabs.value.find(tab => tab.id === 'Index')!)

watch(activeTab, (activeTab) => {
  activeTab.onClick()
})

connect()

async function joinChannel(channel) {
  socket.value?.emit('join-channel', { channelId: channel.id })
}

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

  socket.on('channel-removed', (channelId) => {
    const idx = channels.value.findIndex(channel => channel.id === channelId)

    if (idx === -1)
      return

    channels.value.splice(idx, 1)

    triggerRef(channels)
  })

  socket.on('channel-created', (channel) => {
    channels.value.push(channel)

    triggerRef(channels)
  })
}, { immediate: true })
</script>
