<script lang="ts" setup>
import {storeToRefs} from 'pinia'
import {useChannelStore} from '@/stores/channel'
import {useCategoryStore} from '@/stores/category'
import {computed, onMounted, onUnmounted, ref, watch} from 'vue'
import {useRoute} from 'vue-router'
import CreateChannelDialog from '@/components/channel/CreateChannelDialog.vue'
import CreateCategoryDialog from '@/components/category/CreateCategoryDialog.vue'
import {type MenuItem, useContextMenu} from '@/composables/useContextMenu'
import {useUserStore} from "@/stores/user.ts";
import {useServerStore} from "@/stores/server.ts";
import ChannelPermissionsDialog from '@/components/permissions/ChannelPermissionsDialog.vue'
import {useAuthStore} from '@/stores/auth'
import ServerSettingsDialog from '@/components/server/ServerSettingsDialog.vue'
import {onReloadAll} from '@/plugins/events.ts'

const props = defineProps<{
  serverId: string
  channelId?: string
}>()

const route = useRoute()
const channelStore = useChannelStore()
const categoryStore = useCategoryStore()
const userStore = useUserStore()
const serverStore = useServerStore()
const {currentTree} = storeToRefs(serverStore)
const {openContextMenu} = useContextMenu()
const authStore = useAuthStore()
const showPermissionsDialog = ref(false)
const selectedChannel = ref<any | null>(null)
const showServerSettings = ref(false)
const serverName = computed(() => serverStore.servers.find(server => server.id === props.serverId)?.name || 'Serveur')


const loadServerData = async (targetServerId: string) => {
  if (!targetServerId) return
  channelStore.reset()
  categoryStore.reset()
  userStore.reset()
  try {
    await Promise.all([
      userStore.fetchUsers(targetServerId),
      serverStore.fetchServerTree(targetServerId)
    ])
    syncOpenedCategories()
  } catch (error) {
    console.error('Failed to load server-scoped channels and categories:', error)
  }
}

let stopReloadAll: (() => void) | null = null

onMounted(() => {
  stopReloadAll = onReloadAll(() => loadServerData(props.serverId))
})

onUnmounted(() => {
  stopReloadAll?.()
})

watch(
  () => props.serverId,
  async (newServerId) => {
    if (newServerId) {
      await loadServerData(newServerId)
    }
  },
  {immediate: true}
)

const showChannelDialog = ref(false)
const showCategoryDialog = ref(false)
const selectedCategoryId = ref<string | null>(null)
const openedCategories = ref<string[]>([])

function syncOpenedCategories() {
  openedCategories.value = currentTree.value
    .filter((item) => 'Category' in item)
    .map((item) => item.Category[0].id)
}

async function refreshServerTree() {
  await serverStore.fetchServerTree(props.serverId)
  syncOpenedCategories()
}

// Right click menu (sidebar)
function onSidebarContextMenu(event: MouseEvent) {
  const menuItems: MenuItem[] = [
    {
      label: 'Nouveau canal',
      icon: 'mdi-plus',
      action: () => {
        selectedCategoryId.value = null
        showChannelDialog.value = true
      },
    },
    {
      label: 'Nouvelle catégorie',
      icon: 'mdi-folder-plus',
      action: () => { showCategoryDialog.value = true },
    }
  ]
  openContextMenu(event, menuItems);
}

function onCategoryContextMenu(event: MouseEvent, category: any) {
  const menuItems: MenuItem[] = [
    {
      label: 'Nouveau canal',
      icon: 'mdi-plus',
      action: () => {
        selectedCategoryId.value = category.id
        showChannelDialog.value = true
      },
    },
  ]
  openContextMenu(event, menuItems)
}

// Right click menu (channel)
async function openEditDialog(channel: any) {
  console.log("edit dialog clicked")
}

async function deleteChannel(channelId: string) {
  console.log("delete channel clicked")
}

function onChannelContextMenu(event: MouseEvent, channel: any) {
  const menuItems: MenuItem[] = [
    ...(authStore.isAdmin ? [{
      label: 'Gérer les permissions',
      icon: 'mdi-shield-key',
      action: () => {
        selectedChannel.value = channel
        showPermissionsDialog.value = true
      },
    }] : []),
    {
      label: 'Marquer comme lu',
      icon: 'mdi-check',
      action: () => console.log('Marqué comme lu', channel.id),
    },
    {
      label: 'Modifier le canal',
      icon: 'mdi-pencil',
      action: () => openEditDialog(channel),
    },
    {
      label: 'Supprimer le canal',
      icon: 'mdi-delete',
      color: 'error',
      action: () => deleteChannel(channel.id),
    },
  ]
  openContextMenu(event, menuItems);
}


</script>

<template>
  <v-navigation-drawer width="244" @contextmenu="onSidebarContextMenu">
    <v-sheet color="grey-lighten-5" height="128" width="100%" class="pa-3">
      <v-btn block variant="text" prepend-icon="mdi-cog" @click="showServerSettings = true">Gérer le serveur</v-btn>
    </v-sheet>

    <v-list
      v-model:opened="openedCategories"
      open-strategy="multiple"
      density="compact"
    >
      <template v-for="(item, index) in currentTree" :key="index">
        <!-- Catégorie et ses canaux enfants -->
        <v-list-group v-if="'Category' in item" :value="item.Category[0].id">
          <template #activator="{ props: groupProps }">
            <v-list-item
              :title="item.Category[0].name"
              v-bind="groupProps"
              @contextmenu="onCategoryContextMenu($event, item.Category[0])"
            />
          </template>

          <v-list-item
            v-for="channel in item.Category[1]"
            :key="channel.id"
            :title="channel.name"
            :to="`/server/${serverId}/channel/${channel.id}`"
            :class="{ 'font-weight-bold': (channel.unread_count ?? 0) > 0 }"
            link
            @contextmenu="onChannelContextMenu($event, channel)"
          >
            <template #append>
              <v-chip
                v-if="(channel.unread_count ?? 0) > 0"
                color="primary"
                density="compact"
                size="small"
                variant="flat"
              >
                {{ channel.unread_count }}
              </v-chip>
            </template>
          </v-list-item>
        </v-list-group>

        <!-- Canal orphelin (racine) -->
        <v-list-item
          v-else-if="'Channel' in item"
          :key="item.Channel.id"
          :title="item.Channel.name"
          :to="`/server/${serverId}/channel/${item.Channel.id}`"
          :class="{ 'font-weight-bold': (item.Channel.unread_count ?? 0) > 0 }"
          link
          @contextmenu="onChannelContextMenu($event, item.Channel)"
        >
          <template #append>
            <v-chip
              v-if="(item.Channel.unread_count ?? 0) > 0"
              color="primary"
              density="compact"
              size="small"
              variant="flat"
            >
              {{ item.Channel.unread_count }}
            </v-chip>
          </template>
        </v-list-item>
      </template>
    </v-list>
  </v-navigation-drawer>

  <CreateChannelDialog
    v-model="showChannelDialog"
    :category-id="selectedCategoryId"
    :server-id="serverId"
    @created="refreshServerTree"
  />

  <CreateCategoryDialog
    v-model="showCategoryDialog"
    :server-id="serverId"
    @created="refreshServerTree"
  />

  <ChannelPermissionsDialog
    v-model="showPermissionsDialog"
    :channel="selectedChannel"
    :server-id="serverId"
  />

  <ServerSettingsDialog
    v-model="showServerSettings"
    :server-id="serverId"
    :server-name="serverName"
  />

  <v-main>
    <router-view/>
  </v-main>
</template>
