<template>
  <div class="w-full">
    <Combobox v-model="selected" :disabled="!enabled">
      <ComboboxLabel v-if="!usePlaceholder">{{ title }}</ComboboxLabel>
      <div class="relative">
        <div
          class="rounded-md shadow-sm relative block w-full border border-gray-300 focus:border-primary placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-0 focus:z-10 sm:text-sm resize-none"
        >
          <ComboboxInput
            class="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0"
            :displayValue="(equipment) => selectedEquipment?.name ?? ''"
            @input="query = $event.target.value"
            :placeholder="usePlaceholder ? title : ''"
          />
          <ComboboxButton class="absolute inset-y-0 right-0 flex items-center pr-2">
            <ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
          </ComboboxButton>
        </div>
        <TransitionRoot
          leave="transition ease-in duration-100"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
          @after-leave="query = ''"
        >
          <ComboboxOptions
            class="absolute z-20 mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-300 bg-white py-1 text-base shadow-md ring-1 ring-black/5 focus:outline-none sm:text-sm"
          >
            <div
              v-if="availableEquipment.length === 0"
              class="relative cursor-default select-none px-4 py-2 text-gray-700"
            >
              Keine Auswahl verfügbar
            </div>

            <div
              v-if="filtered.length === 0 && query !== ''"
              class="relative cursor-default select-none px-4 py-2 text-gray-700"
            >
              Keine Treffer
            </div>

            <ComboboxOption
              v-for="person in filtered"
              as="template"
              :key="person.id"
              :value="person.id"
              v-slot="{ selected, active }"
            >
              <li
                class="relative cursor-default select-none py-2 pl-10 pr-4"
                :class="{
                  'bg-primary text-white': active,
                  'text-gray-900': !active,
                }"
              >
                <span class="block truncate" :class="{ 'font-medium': selected, 'font-normal': !selected }">
                  {{ person.name }}
                </span>
                <span
                  v-if="selected"
                  class="absolute inset-y-0 left-0 flex items-center pl-3"
                  :class="{ 'text-white': active, 'text-primary': !active }"
                >
                  <CheckIcon class="h-5 w-5" aria-hidden="true" />
                </span>
              </li>
            </ComboboxOption>
          </ComboboxOptions>
        </TransitionRoot>
      </div>
    </Combobox>
  </div>
</template>

<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import {
  Combobox,
  ComboboxInput,
  ComboboxButton,
  ComboboxOptions,
  ComboboxOption,
  TransitionRoot,
  ComboboxLabel,
} from "@headlessui/vue";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
import type { EquipmentViewModel } from "@/viewmodels/admin/configuration/equipment.models";
</script>

<script lang="ts">
export default defineComponent({
  props: {
    title: String,
    usePlaceholder: {
      type: Boolean,
      default: false,
    },
    enabled: {
      type: Boolean,
      default: true,
    },
    modelValue: {
      type: String,
      default: "",
    },
    availableEquipment: {
      type: Array as PropType<Array<EquipmentViewModel>>,
      default: [],
    },
  },
  data() {
    return {
      query: "" as string,
    };
  },
  computed: {
    selected: {
      get() {
        return this.modelValue;
      },
      set(val: Array<string>) {
        this.$emit("update:model-value", val);
      },
    },
    selectedEquipment() {
      return this.availableEquipment.find((ae) => ae.id == this.selected);
    },
    filtered() {
      return this.query == ""
        ? this.availableEquipment
        : this.availableEquipment.filter((e) => {
            const arr = this.query.toLocaleLowerCase().split(" ");
            return arr.some((q) => e.name.toLocaleLowerCase().includes(q) || e.code?.toLocaleLowerCase().includes(q));
          });
    },
  },
});
</script>
