<script setup lang="ts">
import { computed, ref } from 'vue'
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
import type { CollectionObject } from '@MailManager/models/collection'
import type { ServiceObject } from '@MailManager/models'

interface Props {
  folder: CollectionObject
  service: ServiceObject
  selectedFolderKey: string | null
}

const props = defineProps<Props>()
const collectionsStore = useCollectionsStore()

const emit = defineEmits<{
  select: [folder: CollectionObject]
}>()

const expanded = ref(false)

const folderKeyFor = (folder: CollectionObject): string => {
  return `${folder.provider}:${String(folder.service)}:${String(folder.identifier)}`
}

const folderLabelFor = (folder: CollectionObject): string => {
  return folder.properties.label || String(folder.identifier)
}

const folderIconFor = (folder: CollectionObject): string => {
  switch (folder.properties.role) {
    case 'inbox':
      return 'mdi-inbox'
    case 'sent':
      return 'mdi-send'
    case 'drafts':
      return 'mdi-file-document'
    case 'trash':
      return 'mdi-delete'
    case 'junk':
      return 'mdi-alert-octagon'
    case 'archive':
      return 'mdi-archive'
    case 'outbox':
      return 'mdi-tray-arrow-up'
    default:
      return 'mdi-folder'
  }
}

const folderColorFor = (folder: CollectionObject): string | undefined => {
  switch (folder.properties.role) {
    case 'inbox':
      return 'primary'
    case 'sent':
      return 'success'
    case 'drafts':
      return 'warning'
    case 'trash':
      return 'error'
    case 'junk':
      return 'orange'
    default:
      return undefined
  }
}

const key = computed(() => folderKeyFor(props.folder))

const childFolders = computed(() => {
  const serviceIdentifier = props.service.identifier

  if (serviceIdentifier === null) {
    return []
  }

  return collectionsStore.collectionsInCollection(props.service.provider, serviceIdentifier, props.folder.identifier)
})

const hasChildren = computed(() => {
  const serviceIdentifier = props.service.identifier

  if (serviceIdentifier === null) {
    return false
  }

  return collectionsStore.hasChildrenInCollection(props.service.provider, serviceIdentifier, props.folder.identifier)
})
const isSelected = computed(() => props.selectedFolderKey === key.value)

const onSelect = () => {
  emit('select', props.folder)
}

const toggleExpanded = () => {
  expanded.value = !expanded.value
}

const onGroupDoubleClick = () => {
  toggleExpanded()
  onSelect()
}
</script>

<template>
  <div
    v-if="hasChildren"
    class="folder-node-group"
  >
    <v-list-item
      class="folder-node"
      :title="folderLabelFor(folder)"
      :active="isSelected"
      @click="onSelect"
      @dblclick.stop="onGroupDoubleClick"
    >
      <template #prepend>
        <v-icon
          :icon="folderIconFor(folder)"
          :color="folderColorFor(folder)"
        />
      </template>

      <template #append>
        <v-btn
          variant="text"
          density="compact"
          size="x-small"
          :icon="expanded ? 'mdi-chevron-down' : 'mdi-chevron-right'"
          @click.stop="toggleExpanded"
        />
      </template>
    </v-list-item>

    <div
      v-if="expanded"
      class="folder-node-children"
    >
      <FolderSelectionTreeNode
        v-for="childFolder in childFolders"
        :key="folderKeyFor(childFolder)"
        :folder="childFolder"
        :service="service"
        :selected-folder-key="selectedFolderKey"
        @select="emit('select', $event)"
      />
    </div>
  </div>

  <v-list-item
    v-else
    class="folder-node"
    :title="folderLabelFor(folder)"
    :active="isSelected"
    @click="onSelect"
  >
    <template #prepend>
      <v-icon
        :icon="folderIconFor(folder)"
        :color="folderColorFor(folder)"
      />
    </template>
  </v-list-item>
</template>

<style scoped>
.folder-node {
  --v-list-item-prepend-size: 22px;
}

.folder-node.v-list-item--active {
  background-color: rgba(var(--v-theme-primary), 0.12);
}

.folder-node :deep(.v-list-item__prepend) {
  padding-inline-start: 4px;
  margin-inline-end: 2px;
}

.folder-node-children {
  padding-left: 12px;
  margin-left: 8px;
  border-left: 2px solid rgba(var(--v-border-color), 0.3);
}
</style>
