<template>
  <div class="flex flex-row gap-2 items-center w-full">
    <select v-model="column" class="w-full">
      <option value="" disabled>Spalte auswählen</option>
      <option
        v-for="selectable in selectableColumns"
        :value="`${selectable.id}_${selectable.column}`"
        :disabled="
          alreadySorted.some((as) => as.id == selectable.id && as.col == selectable.column) &&
          `${selectable.id}_${selectable.column}` != column
        "
      >
        {{ [...selectable.path, selectable.table].join("-") }} -> {{ selectable.column }}
      </option>
    </select>
    <select v-model="order">
      <option value="" disabled>Sortierung auswählen</option>
      <option v-for="order in orderable" :value="order.key">
        {{ order.val }}
      </option>
    </select>
    <div class="p-1 border border-gray-400 hover:bg-gray-200 rounded-md" @click="$emit('remove')">
      <TrashIcon class="text-gray-500 h-6 w-6 cursor-pointer" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { defineComponent, type PropType } from "vue";
import { mapActions, mapState } from "pinia";
import type { OrderByStructure, OrderByType } from "@/types/dynamicQueries";
import { useQueryBuilderStore } from "@/stores/admin/club/queryBuilder";
import { TrashIcon } from "@heroicons/vue/24/outline";
</script>

<script lang="ts">
export default defineComponent({
  props: {
    table: {
      type: String,
      default: "",
    },
    // columns: {
    //   type: [Array, String] as PropType<"*" | Array<string>>,
    //   default: "*",
    // },
    columns: {
      type: Array as PropType<
        Array<{ table: string; id: string; depth: number; path: string[]; columns: "*" | string[] }>
      >,
      default: [],
    },
    modelValue: {
      type: Object as PropType<OrderByStructure>,
      default: {},
    },
    alreadySorted: {
      type: Array as PropType<Array<{ id: string; col: string }>>,
      default: [],
    },
  },
  emits: ["update:model-value", "remove"],
  watch: {
    columns() {
      if (!this.columns.some((c) => c.id == this.modelValue.id)) {
        this.$emit("remove");
      }
    },
  },
  data() {
    return {
      orderable: [
        { key: "ASC", val: "Aufsteigend (ABC)" },
        { key: "DESC", val: "Absteigend (CBA)" },
      ],
    };
  },
  computed: {
    ...mapState(useQueryBuilderStore, ["tableMetas"]),
    // selectableColumns() {
    //   if (this.columns == "*") {
    //     let meta = this.tableMetas.find((tm) => tm.tableName == this.table);
    //     if (!meta) return [];
    //     let relCols = meta.relations.map((r) => r.column);
    //     return meta.columns.map((c) => c.column).filter((c) => !relCols.includes(c));
    //   } else {
    //     return this.columns;
    //   }
    // },
    selectableColumns() {
      return this.columns.reduce(
        (acc, curr) => {
          if (curr.columns == "*") {
            let meta = this.tableMetas.find((tm) => tm.tableName == this.table);
            if (meta) {
              let relCols = meta.relations.map((r) => r.column);
              meta.columns
                .map((c) => c.column)
                .filter((c) => !relCols.includes(c))
                .forEach((c) =>
                  acc.push({ id: curr.id, depth: curr.depth, table: curr.table, column: c, path: curr.path })
                );
            }
          } else {
            curr.columns.forEach((c) =>
              acc.push({ id: curr.id, depth: curr.depth, table: curr.table, column: c, path: curr.path })
            );
          }
          return acc;
        },
        [] as Array<{ id: string; depth: number; table: string; column: string; path: string[] }>
      );
    },
    column: {
      get() {
        return `${this.modelValue.id}_${this.modelValue.column}`;
      },
      set(val: `${string}_${string}`) {
        let col = this.selectableColumns.find((sc) => sc.id == val.split("_")[0] && sc.column == val.split("_")[1]);
        this.$emit("update:model-value", { ...this.modelValue, ...col });
      },
    },
    order: {
      get() {
        return this.modelValue.order;
      },
      set(val: OrderByType) {
        this.$emit("update:model-value", { ...this.modelValue, order: val });
      },
    },
  },
});
</script>
