<script setup lang="ts">
import type { TreeItem } from './type'
import { ChevronsUpDown } from 'lucide-vue-next'
import { cn } from '~/lib/utils'
import TreeView from './tree-view.vue'

const props = defineProps<{
  data: TreeItem[]
  onFetchChildren: (parentId: string) => Promise<void>
}>()

const modelValue = defineModel<string>()
const open = ref(false)
const searchValue = ref('')

function handleSelect(newVal: string) {
  modelValue.value = newVal
  open.value = false
}

function findLabel(value: string, items: TreeItem[]): string | undefined {
  for (const item of items) {
    if (item.value === value) return item.label
    if (item.children) {
      const found = findLabel(value, item.children)
      if (found) return found
    }
  }
}

const selectedLabel = computed(() => {
  return modelValue.value ? findLabel(modelValue.value, props.data) : '--- select item'
})

const filteredData = computed(() => {
  if (!searchValue.value) return props.data
  // recursive filter
  function filterTree(items: TreeItem[]): TreeItem[] {
    return items
      .map((item) => {
        const match = item.label.toLowerCase().includes(searchValue.value.toLowerCase())
        let children: TreeItem[] | undefined = undefined
        if (item.children) {
          children = filterTree(item.children)
        }
        if (match || (children && children.length > 0)) {
          return { ...item, children }
        }
        return null
      })
      .filter(Boolean) as TreeItem[]
  }
  return filterTree(props.data)
})
</script>

<template>
  <Popover v-model:open="open">
    <PopoverTrigger as-child>
      <Button
        variant="outline"
        role="combobox"
        class="w-full justify-between border border-slate-200 bg-white text-black dark:border-slate-700 dark:bg-slate-800 dark:text-white"
      >
        <span
          class="font-normal text-muted-foreground"
          :class="cn('font-normal', !modelValue && 'text-muted-foreground', modelValue && 'text-black')"
        >
          {{ selectedLabel }}
        </span>
        <ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
      </Button>
    </PopoverTrigger>
    <PopoverContent
      class="min-w-full max-w-[350px] border border-slate-200 bg-white p-0 text-black dark:border-slate-700 dark:bg-slate-800 dark:text-white"
    >
      <Command>
        <CommandInput
          placeholder="Cari item..."
          v-model="searchValue"
        />
        <CommandEmpty>Item tidak ditemukan.</CommandEmpty>
        <CommandList class="max-h-[300px] overflow-x-auto overflow-y-auto">
          <CommandGroup>
            <TreeView
              :data="filteredData"
              :selected-value="modelValue"
              :on-fetch-children="onFetchChildren"
              :level="0"
              @select="handleSelect"
            />
          </CommandGroup>
        </CommandList>
      </Command>
    </PopoverContent>
  </Popover>
</template>
