<script setup lang="ts">
import { ref, watch } from "vue";

export interface SuggestionItem {
  label: string;
  value: string;
}

const props = defineProps<{
  items: SuggestionItem[];
  command: (item: SuggestionItem) => void;
}>();

const selectedIndex = ref(0);

watch(
  () => props.items,
  () => {
    selectedIndex.value = 0;
  }
);

function onKeyDown(event: KeyboardEvent): boolean {
  if (event.key === "ArrowUp") {
    event.preventDefault();
    selectedIndex.value =
      (selectedIndex.value - 1 + props.items.length) % props.items.length;
    return true;
  }
  if (event.key === "ArrowDown") {
    event.preventDefault();
    selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
    return true;
  }
  if (event.key === "Enter" || event.key === "Tab") {
    event.preventDefault();
    selectItem(selectedIndex.value);
    return true;
  }
  return false;
}

function selectItem(index: number) {
  const item = props.items[index];
  if (item) {
    props.command(item);
  }
}

defineExpose({ onKeyDown });
</script>

<template>
  <ul v-if="items.length" class="ac-dropdown suggestion-dropdown">
    <li
      v-for="(item, i) in items"
      :key="item.value"
      :class="['ac-item', { active: i === selectedIndex }]"
      @mousedown.prevent="selectItem(i)"
    >
      {{ item.label }}
    </li>
  </ul>
</template>

<style scoped>
.suggestion-dropdown {
  position: relative;
  z-index: 100;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--fs-border-color);
  border-radius: var(--fs-radius-sm);
  background: var(--fs-surface-raised);
  box-shadow: 0 4px 12px var(--color-shadow);
  max-height: 200px;
  overflow-y: auto;
  min-width: 160px;
}
.ac-item {
  padding: 0.4rem 0.75rem;
  cursor: pointer;
  font-size: 0.9rem;
}
.ac-item:hover,
.ac-item.active {
  background: var(--fs-surface-raised);
}
</style>
