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

const props = defineProps<{
  modelValue?: string | null;
  options: Array<{ id: string; number?: string | null; name: string }>;
  placeholder?: string;
  allowEmpty?: boolean;
  emptyLabel?: string;
  required?: boolean;
}>();

const emit = defineEmits<{
  "update:modelValue": [value: string | null];
  change: [value: string | null];
}>();

const query = ref("");
const open = ref(false);

const selected = computed(() => props.options.find((option) => option.id === props.modelValue));
const normalizedQuery = computed(() => query.value.trim().toLowerCase());
const filteredOptions = computed(() => {
  const activeQuery = normalizedQuery.value;
  const matches = activeQuery
    ? props.options.filter((option) => {
        const haystack = `${option.number ?? ""} ${option.name}`.toLowerCase();
        return haystack.includes(activeQuery);
      })
    : props.options;

  return matches.slice(0, 20);
});

function select(value: string | null) {
  emit("update:modelValue", value);
  emit("change", value);
  query.value = "";
  open.value = false;
}

function closeSoon() {
  window.setTimeout(() => {
    open.value = false;
  }, 120);
}
</script>

<template>
  <div class="search-select">
    <input
      v-model="query"
      type="search"
      :placeholder="placeholder ?? 'Nach Nummer oder Name suchen'"
      :required="required && !modelValue"
      @focus="open = true"
      @input="open = true"
      @blur="closeSoon"
    />
    <div v-if="selected" class="search-select-current">
      Ausgewählt: <strong>{{ selected.number ? `${selected.number} - ${selected.name}` : selected.name }}</strong>
    </div>
    <div v-if="open" class="search-select-options">
      <button
        v-if="allowEmpty"
        type="button"
        class="search-option"
        :class="{ selected: modelValue === null || modelValue === '' }"
        @click="select(null)"
      >
        {{ emptyLabel ?? "Keine Auswahl" }}
      </button>
      <button
        v-for="option in filteredOptions"
        :key="option.id"
        type="button"
        class="search-option"
        :class="{ selected: modelValue === option.id }"
        @click="select(option.id)"
      >
        <span>{{ option.number }}</span>
        <strong>{{ option.name }}</strong>
      </button>
      <p v-if="filteredOptions.length === 0" class="muted">Keine Treffer.</p>
    </div>
  </div>
</template>
