<script setup>
/**
 * ColumnPicker – kolomkiezer met drag & drop volgorde, zichtbaarheid en zoekveld.
 * Emits: update:visibleKeys, update:orderedKeys
 */
import draggable from "vuedraggable/src/vuedraggable.js";
import { computed, ref } from "vue";

const props = defineProps({
  /** Alle kolomdefinities (key, header, defaultVisible) */
  allColumns: {
    type: Array,
    default: () => [],
  },
  /** Keys van zichtbare kolommen */
  visibleKeys: {
    type: Array,
    default: () => [],
  },
  /** Volgorde van alle kolom-keys (voor drag reorder) */
  orderedKeys: {
    type: Array,
    default: () => [],
  },
  /** Keys die vast vooraan blijven en niet via drag verplaatsbaar zijn */
  pinnedKeys: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits(["update:visibleKeys", "update:orderedKeys"]);

const searchQuery = ref("");

const keyToColumn = computed(() => {
  const map = new Map();
  (props.allColumns || []).forEach((c) => map.set(c.key, c));
  return map;
});

const pinnedSet = computed(() => new Set(props.pinnedKeys || []));

/** Pinned keys in table order (only keys that exist in orderedKeys). */
const pinnedInOrder = computed(() =>
  (props.orderedKeys || []).filter((k) => pinnedSet.value.has(k)),
);

/** Keys die de gebruiker mag herschikken (niet vastgepind). */
const draggableKeys = computed(() =>
  (props.orderedKeys || []).filter((k) => !pinnedSet.value.has(k)),
);

const filteredOrderedKeys = computed(() => {
  const q = (searchQuery.value || "").trim().toLowerCase();
  if (!q) return [...(props.orderedKeys || [])];
  const keyToCol = keyToColumn.value;
  return (props.orderedKeys || []).filter((key) => {
    const col = keyToCol.get(key);
    return col && (col.header || key).toLowerCase().includes(q);
  });
});

const draggableList = computed({
  get() {
    return [...draggableKeys.value];
  },
  set(val) {
    if (!Array.isArray(val)) return;
    emit("update:orderedKeys", [...pinnedInOrder.value, ...val]);
  },
});

function isVisible(key) {
  return (props.visibleKeys || []).includes(key);
}

function isLastVisible(key) {
  const current = props.visibleKeys || [];
  return current.length === 1 && current[0] === key;
}

function setVisible(key, visible) {
  const current = props.visibleKeys || [];
  if (visible) {
    if (!current.includes(key)) emit("update:visibleKeys", [...current, key]);
  } else {
    // Prevent hiding the last visible column – at least one must remain.
    if (current.length <= 1) return;
    emit(
      "update:visibleKeys",
      current.filter((k) => k !== key),
    );
  }
}

function toggleVisible(key) {
  setVisible(key, !isVisible(key));
}

function resetToDefault() {
  const cols = props.allColumns || [];
  const pinned = (props.pinnedKeys || []).filter((k) =>
    cols.some((c) => c.key === k),
  );
  const rest = cols.map((c) => c.key).filter((k) => !pinned.includes(k));
  const defaultOrder = [...pinned, ...rest];
  const defaultVisible = cols
    .filter((c) => c.defaultVisible !== false)
    .map((c) => c.key);
  emit("update:orderedKeys", defaultOrder);
  emit("update:visibleKeys", defaultVisible);
}
</script>

<template>
  <div class="column-picker flex flex-col gap-3 min-w-[14rem]">
    <IconField>
      <InputIcon>
        <i class="pi pi-search" />
      </InputIcon>
      <InputText
        v-model="searchQuery"
        placeholder="Kolom zoeken..."
        class="w-full"
      />
    </IconField>

    <div class="flex items-center justify-between">
      <span class="font-semibold text-sm">Zichtbare kolommen</span>
      <Button
        label="Reset naar standaard"
        link
        size="small"
        class="p-0 text-sm"
        @click="resetToDefault"
      />
    </div>

    <!-- Zonder zoekterm: vastgepinde kolommen + drag & drop voor de rest -->
    <div v-if="!searchQuery.trim()" class="flex flex-col gap-1">
      <div
        v-for="key in pinnedInOrder"
        :key="`pin-${key}`"
        class="flex items-center gap-2 py-1 opacity-90"
      >
        <i
          class="pi pi-lock text-surface-400 text-sm shrink-0"
          title="Vaste positie"
        />
        <span class="flex-1 text-sm truncate">{{
          keyToColumn.get(key)?.header ?? key
        }}</span>
        <Checkbox
          :model-value="isVisible(key)"
          :binary="true"
          :disabled="isLastVisible(key)"
          @update:model-value="toggleVisible(key)"
        />
      </div>
      <draggable
        v-model="draggableList"
        :item-key="(key) => key"
        handle=".column-picker-drag-handle"
        tag="div"
        class="flex flex-col gap-1"
      >
        <template #item="{ element: key }">
          <div class="flex items-center gap-2 py-1">
            <i
              class="pi pi-bars column-picker-drag-handle cursor-grab text-surface-500 text-sm"
            />
            <span class="flex-1 text-sm truncate">{{
              keyToColumn.get(key)?.header ?? key
            }}</span>
            <Checkbox
              :model-value="isVisible(key)"
              :binary="true"
              :disabled="isLastVisible(key)"
              @update:model-value="toggleVisible(key)"
            />
          </div>
        </template>
      </draggable>
    </div>

    <!-- Met zoekterm: alleen gevonden kolommen (geen drag) -->
    <div v-else class="flex flex-col gap-1">
      <div
        v-for="key in filteredOrderedKeys"
        :key="key"
        class="flex items-center gap-2 py-1"
      >
        <i class="pi pi-bars text-surface-400 text-sm opacity-50" />
        <span class="flex-1 text-sm truncate">{{
          keyToColumn.get(key)?.header ?? key
        }}</span>
        <Checkbox
          :model-value="isVisible(key)"
          :binary="true"
          :disabled="isLastVisible(key)"
          @update:model-value="toggleVisible(key)"
        />
      </div>
      <span
        v-if="filteredOrderedKeys.length === 0"
        class="text-sm text-surface-500"
        >Geen kolommen gevonden</span
      >
    </div>
  </div>
</template>
