<template>
  <div>
    <div
      class="deck-node d-flex align-center px-3 py-2 rounded"
      :class="{ selected: isSelected }"
      @click="$emit('select', deck)"
    >
      <v-btn
        icon
        variant="text"
        density="comfortable"
        size="default"
        class="mr-1"
        @click.stop="expanded = !expanded"
      >
        <v-icon size="default">
          {{ expanded ? "mdi-chevron-down" : "mdi-chevron-right" }}
        </v-icon>
      </v-btn>
      <v-icon
        size="default"
        class="mr-2 text-medium-emphasis"
        :icon="expanded && hasChildren ? 'mdi-folder-open-outline' : 'mdi-folder-outline'"
      />
      <span
        class="flex-grow-1 text-body-1"
        :class="{ 'font-weight-medium': isSelected }"
      >
        {{ deck.name }}
      </span>
      <div
        class="kebab-btn"
        @click.stop
      >
        <FlashcardDeckKebab
          :flashcard-deck-id="deck.id"
          @created="$emit('created', $event)"
          @updated="$emit('updated', $event)"
          @deleted="$emit('deleted', $event)"
        />
      </div>
    </div>

    <div
      v-show="expanded"
      class="pl-5"
    >
      <draggable
        v-model="children"
        :group="{ name: 'decks' }"
        item-key="id"
        @change="onChange"
      >
        <template #item="{ element }">
          <FlashcardDeckTreeNode
            v-model:children="element.children"
            :deck="element"
            :selected-id="selectedId"
            @select="$emit('select', $event)"
            @move="$emit('move', $event)"
            @created="$emit('created', $event)"
            @updated="$emit('updated', $event)"
            @deleted="$emit('deleted', $event)"
          />
        </template>
      </draggable>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue"
import draggable from "vuedraggable"

import type { DeckNode } from "@/components/flashcard-decks/FlashcardDeckTree.vue"
import FlashcardDeckKebab from "@/components/flashcard-decks/FlashcardDeckKebab.vue"

const props = defineProps<{
  deck: DeckNode
  selectedId?: number | null
}>()

const children = defineModel<DeckNode[]>("children", { required: true })

const emit = defineEmits<{
  select: [deck: DeckNode]
  move: [payload: { deckId: number; newParentId: number | null }]
  created: [flashcardDeckId: number]
  updated: [flashcardDeckId: number]
  deleted: [flashcardDeckId: number]
}>()

const expanded = ref(false)
const isSelected = computed(() => props.selectedId === props.deck.id)
const hasChildren = computed(() => children.value.length > 0)

function onChange(event: { added?: { element: DeckNode } }) {
  if (event.added) {
    emit("move", { deckId: event.added.element.id, newParentId: props.deck.id })
  }
}
</script>

<style scoped>
.deck-node {
  cursor: grab;
  user-select: none;
}

.deck-node:hover {
  background: rgb(var(--v-theme-hoverColor));
}

.deck-node.selected {
  background: rgb(var(--v-theme-lightprimary));
}

.kebab-btn {
  opacity: 0;
  transition: opacity 0.15s;
}

.deck-node:hover .kebab-btn {
  opacity: 1;
}
</style>
