<script setup>
import { ref, computed, watch } from "vue";
import { Popover, PopoverTrigger, PopoverContent } from "@/Components/ui/popover";
import {
  Command,
  CommandInput,
  CommandList,
  CommandEmpty,
  CommandGroup,
  CommandItem,
} from "@/Components/ui/command";
import { Button } from "@/Components/ui/button";
import { Badge } from "@/Components/ui/badge";
import { Check, ChevronsUpDown, X } from "lucide-vue-next";

const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  items: { type: Array, default: () => [] }, // [{ value, label }]
  placeholder: { type: String, default: "Izberi..." },
  searchPlaceholder: { type: String, default: "Išči..." },
  emptyText: { type: String, default: "Ni zadetkov." },
  disabled: { type: Boolean, default: false },
  max: { type: Number, default: null },
  clearable: { type: Boolean, default: true },
  contentClass: { type: String, default: "p-0 w-[300px]" },
  showSelectedChips: { type: Boolean, default: true },
  chipVariant: { type: String, default: "secondary" },
});

const emit = defineEmits(["update:modelValue"]);

const open = ref(false);
const query = ref("");
const internal = ref([...props.modelValue]);

watch(
  () => props.modelValue,
  (val) => {
    if (!Array.isArray(val)) return;
    internal.value = [...val];
  }
);

const valueSet = computed(() => new Set(internal.value.map(String)));

const filteredItems = computed(() => {
  const q = query.value.trim().toLowerCase();
  if (!q) return props.items;
  return props.items.filter((i) => i.label.toLowerCase().includes(q));
});

function toggle(value) {
  if (props.disabled) return;
  const v = String(value);
  const set = new Set(internal.value.map(String));
  if (set.has(v)) {
    set.delete(v);
  } else {
    if (props.max && set.size >= props.max) return;
    set.add(v);
  }
  internal.value = Array.from(set);
  emit("update:modelValue", internal.value);
  // Clear search so full list remains visible after selection
  query.value = "";
}

function removeChip(value) {
  const v = String(value);
  internal.value = internal.value.filter((x) => String(x) !== v);
  emit("update:modelValue", internal.value);
}

function clearAll() {
  if (!props.clearable || props.disabled) return;
  internal.value = [];
  emit("update:modelValue", internal.value);
}

const summaryText = computed(() => {
  if (internal.value.length === 0) return props.placeholder;
  if (!props.showSelectedChips) return `${internal.value.length} izbranih`;
  const labels = internal.value.map((v) => {
    const found = props.items.find((i) => String(i.value) === String(v));
    return found?.label || v;
  });
  if (labels.length <= 3) return labels.join(', ');
  const firstThree = labels.slice(0, 3).join(', ');
  const remaining = labels.length - 3;
  return `${firstThree}, … +${remaining}`; // show ellipsis and remaining count
});
</script>

<template>
  <Popover v-model:open="open">
    <PopoverTrigger as-child>
      <Button
        variant="outline"
        role="combobox"
        :disabled="disabled"
        class="w-full justify-between gap-2"
      >
        <span
          class="truncate"
          :class="{ 'text-muted-foreground': internal.length === 0 }"
        >
          {{ summaryText }}
        </span>
        <ChevronsUpDown class="h-4 w-4 opacity-50" />
      </Button>
    </PopoverTrigger>
    <PopoverContent :class="contentClass">
      <Command>
        <CommandInput v-model="query" :placeholder="searchPlaceholder" />

        <CommandList>
          <CommandEmpty class="px-3 py-2 text-sm text-muted-foreground">{{
            emptyText
          }}</CommandEmpty>
          <CommandGroup>
            <CommandItem
              v-for="item in filteredItems"
              :key="item.value"
              :value="String(item.value)"
              @select="() => toggle(item.value)"
              class="flex items-center gap-2 px-2 py-1.5 rounded-sm cursor-pointer hover:bg-accent hover:text-accent-foreground"
            >
              <Check
                class="h-4 w-4"
                :class="valueSet.has(String(item.value)) ? 'opacity-100' : 'opacity-0'"
              />
              <span class="flex-1">{{ item.label }}</span>
            </CommandItem>
          </CommandGroup>
        </CommandList>
        <div class="border-t p-2 flex items-center justify-between gap-2">
          <Button
            v-if="clearable"
            variant="outline"
            size="sm"
            :disabled="internal.length === 0 || disabled"
            @click="clearAll"
            >Počisti</Button
          >
          <Button size="sm" :disabled="disabled" @click="open = false">Zapri</Button>
        </div>
        <div
          v-if="showSelectedChips && internal.length"
          class="border-t p-2 flex flex-wrap gap-1"
        >
          <Badge
            v-for="val in internal"
            :key="val"
            :variant="chipVariant"
            class="flex items-center gap-1"
          >
            <span class="truncate max-w-[140px]">
              {{ items.find((i) => String(i.value) === String(val))?.label || val }}
            </span>
            <button
              type="button"
              class="hover:text-foreground/80"
              @click.stop="removeChip(val)"
              :title="'Odstrani'"
            >
              <X class="h-3 w-3" />
            </button>
          </Badge>
        </div>
      </Command>
    </PopoverContent>
  </Popover>
</template>
