<script setup lang="ts">
import { cn } from '~/lib/utils'

interface Item {
  value: string
  label: string
  code?: string
}

const props = defineProps<{
  id: string
  modelValue?: string
  items: Item[]
  placeholder?: string
  searchPlaceholder?: string
  emptyMessage?: string
  class?: string
  disabled?: boolean
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const open = ref(false)

const selectedItem = computed(() =>
  props.items.find(item => item.value === props.modelValue),
)

const displayText = computed(() =>
  selectedItem.value?.label || props.placeholder || '---pilih item',
)

// Create searchable items with combined code and label for better search
// Sort by:
//  1. Selected item first (highest priority)
//  2. Then by label alphabetically
const searchableItems = computed(() => {
  const itemsWithSearch = props.items.map(item => ({
    ...item,
    searchValue: `${item.code || ''} ${item.label}`.trim(),
    isSelected: item.value === props.modelValue,
  }))

  return itemsWithSearch.sort((a, b) => {
    // Selected item always comes first
    if (a.isSelected && !b.isSelected) return -1
    if (!a.isSelected && b.isSelected) return 1

    // If neither or both are selected, sort by label alphabetically
    return a.label.localeCompare(b.label)
  })
})

function onSelect(item: Item) {
  emit('update:modelValue', item.value)
  open.value = false
}
</script>

<template>
  <Popover v-model:open="open">
    <PopoverTrigger as-child>
      <Button
      :id="props.id"
      :disabled="props.disabled"
      variant="outline"
      role="combobox"
      :aria-expanded="open"
      :aria-controls="`${props.id}-list`"
      :aria-describedby="`${props.id}-search`"
      :class="cn(
        'w-full justify-between border-1 border-gray-400 bg-white hover:bg-gray-50 text-sm font-normal focus:outline-none focus:ring-1 focus:ring-black',
        !modelValue && 'text-muted-foreground',
        props.class,
      )"
      >
        {{ displayText }}
        <Icon name="i-lucide-chevrons-up-down" class="ml-2 h-4 w-4 shrink-0 opacity-50" />
      </Button>
    </PopoverTrigger>
    <PopoverContent class="w-full p-0">
      <Command>
        <CommandInput
          :id="`${props.id}-search`"
          class="h-9"
          :placeholder="searchPlaceholder || 'Cari...'"
          :aria-label="`Cari ${displayText}`"
        />
        <CommandEmpty>{{ emptyMessage || 'Item tidak ditemukan.' }}</CommandEmpty>
        <CommandList :id="`${props.id}-list`" role="listbox">
          <CommandGroup>
            <CommandItem v-for="item in searchableItems" :key="item.value" :value="item.searchValue" @select="onSelect(item)">
              <div class="flex items-center justify-between w-full">
                <span>{{ item.label }}</span>
                <div class="flex items-center gap-2">
                  <span v-if="item.code" class="text-xs text-muted-foreground">{{ item.code }}</span>
                  <Icon
                    name="i-lucide-check"
                    :class="cn(
                      'h-4 w-4',
                      modelValue === item.value ? 'opacity-100' : 'opacity-0',
                    )"
                  />
                </div>
              </div>
            </CommandItem>
          </CommandGroup>
        </CommandList>
      </Command>
    </PopoverContent>
  </Popover>
</template>
