<template>
  <div class="flex flex-col gap-2 h-full w-full overflow-hidden">
    <Combobox v-model="presence" multiple :disabled="!enabled">
      <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"
          @input="query = $event.target.value"
          placeholder="suchen..."
        />
        <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>
      <ComboboxOptions
        class="w-full h-full overflow-y-auto flex flex-col gap-1 rounded-md border border-gray-300 text-base shadow-md ring-1 ring-black/5 focus:outline-none sm:text-sm"
        :static="true"
        :open="true"
        :class="enabled ? ' bg-white' : 'opacity-75 pointer-events-none bg-gray-50'"
      >
        <div v-if="availableForces.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-pointer select-none py-2 pl-10 pr-4"
            :class="{
              '!bg-primary text-white': active,
              'text-gray-900': !active,
              'bg-red-200': selected,
            }"
          >
            <span class="block truncate" :class="{ 'font-medium': selected, 'font-normal': !selected }">
              {{ person.firstname }} {{ person.lastname }}
            </span>
            <span
              v-if="selected"
              class="absolute inset-y-0 left-0 flex items-center pl-3"
              :class="{ 'text-white': active && !selected, 'text-primary': !active }"
            >
              <CheckIcon class="h-5 w-5" aria-hidden="true" />
            </span>
          </li>
        </ComboboxOption>
      </ComboboxOptions>
    </Combobox>
  </div>
</template>

<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import { Combobox, ComboboxInput, ComboboxButton, ComboboxOptions, ComboboxOption } from "@headlessui/vue";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
import { useForceStore } from "@/stores/admin/configuration/force";
import { mapState } from "pinia";
import * as Y from "yjs";
import { Awareness } from "@/helpers/awareness";
</script>

<script lang="ts">
export default defineComponent({
  props: {
    document: {
      type: Object as PropType<Y.Doc>,
      required: true,
    },
    awareness: {
      type: Object as PropType<Partial<Awareness>>,
      required: true,
    },
    enabled: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      query: "" as string,
    };
  },
  computed: {
    ...mapState(useForceStore, ["availableForces"]),
    presence: {
      get() {
        return Array.from(this.document.getMap<boolean>("presence").keys());
      },
      set(val: Array<string>) {
        let added = val.filter((e) => !this.document.getMap<boolean>("presence").has(e));
        let removed = Array.from(this.document.getMap<boolean>("presence").keys()).filter((e) => !val.includes(e));

        added.forEach((a) => {
          this.document.getMap<boolean>("presence").set(a, true);
        });

        removed.forEach((r) => {
          this.document.getMap<boolean>("presence").delete(r);
        });
      },
    },
    filtered() {
      return this.query == ""
        ? this.availableForces
        : this.availableForces.filter((f) => {
            const arr = this.query.toLocaleLowerCase().split(" ");
            if (arr.length == 1) {
              return arr.some(
                (q) => f.firstname.toLocaleLowerCase().includes(q) || f.lastname.toLocaleLowerCase().includes(q)
              );
            } else {
              return arr
                .flatMap((v, i) => arr.slice(i + 1).map((w) => [v, w]))
                .some(
                  (q) =>
                    (f.firstname.toLocaleLowerCase().includes(q[0]) && f.lastname.toLocaleLowerCase().includes(q[1])) ||
                    (f.firstname.toLocaleLowerCase().includes(q[1]) && f.lastname.toLocaleLowerCase().includes(q[0]))
                );
            }
          });
    },
  },
});
</script>
