<template>
  <div class="flex gap-2">
    <select
      v-if="showType"
      v-model="ruleset.column"
      class="w-2/6 md:w-3/12 h-10 px-2"
      name="searchType"
      @change="filterTypeChanged"
    >
      <option :value="ClassSelectorColumn.Module" default>Modul</option>
      <option :value="ClassSelectorColumn.Degree" default>Studiengang</option>
      <option :value="ClassSelectorColumn.Room">Raum</option>
      <option :value="ClassSelectorColumn.Class">Klasse</option>
      <option :value="ClassSelectorColumn.Lecturer">Dozent</option>
      <option :value="ClassSelectorColumn.Time">Zeit</option>
      <option :value="ClassSelectorColumn.TeachingType">Art</option>
    </select>

    <div class="w-full justify-center">
      <div
        v-if="ruleset.column == ClassSelectorColumn.Time"
        class="w-full gap-2 grid grid-cols-1"
      >
        <div class="flex items-center">
          <span class="hidden md:inline w-12">Von:</span>
          <WeekdayTimePicker
            v-model="(ruleset.filterData as Record<string, number>).startTime"
            :disable-greater-than="disableUpper"
            class="w-full h-10"
          />
        </div>
        <div class="flex items-center">
          <span class="hidden md:inline w-12">Bis:</span>
          <WeekdayTimePicker
            v-model="(ruleset.filterData as Record<string, number>).endTime"
            :disable-lower-than="disableLower"
            class="w-full h-10"
          />
        </div>
      </div>

      <select
        v-else-if="ruleset.column == ClassSelectorColumn.Degree"
        id="degreeSelector"
        v-model="ruleset.filterData.degree"
        class="w-full h-10"
        @change="
          () =>
            stateStore.updateLastSelectedDegreeProgram(
              ruleset.filterData.degree ?? '',
            )
        "
      >
        <option default value="">Alle</option>
        <option
          v-for="name in classesStore.degreePrograms"
          :key="name"
          :value="name"
        >
          {{ name }}
        </option>
      </select>

      <select
        v-else-if="ruleset.column == ClassSelectorColumn.TeachingType"
        id="teachingTypeSelector"
        v-model="ruleset.filterData.teachingType"
        class="w-full capitalize h-10"
      >
        <option default value="">Alle</option>
        <option v-for="name in TeachingType" :key="name" :value="name">
          {{ name }}
        </option>
      </select>

      <input
        v-else
        v-model="ruleset.filterData.term"
        class="w-full h-10"
        name="search"
        type="text"
        :placeholder="searchPlaceholderText"
        autocomplete="off"
      />
    </div>

    <div
      v-if="showAddRemove"
      class="w-32 h-10 flex justify-center items-center"
    >
      <button
        class="action-button"
        title="Neuen Filter nach diesem einfügen"
        @click="$emit('addFilter', ruleset)"
      >
        <font-awesome-icon icon="fa-solid fa-plus" />
      </button>
      <button
        :disabled="isLastFilter"
        class="action-button"
        title="Diesen Filter entfernen"
        @click="$emit('removeFilter', ruleset)"
      >
        <font-awesome-icon icon="fa-solid fa-minus" />
      </button>
      <div
        title="Filtering ein/ausschalten"
        class="action-checkbox"
        @click="filterEnabledClick(false)"
      >
        <input
          v-model="ruleset.enabled"
          type="checkbox"
          @change="filterEnabledClick(true)"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { PropType } from "vue";
import { useClassesStore } from "../../stores/classes";
import { useStateStore } from "../../stores/state";
import { ClassSelectorColumn, FilterRule, TeachingType } from "../../types";
import WeekdayTimePicker from "../general/WeekdayTimePicker.vue";

export default {
  name: "ClassFilter",
  components: { WeekdayTimePicker },
  props: {
    modelValue: {
      required: true,
      type: Object as PropType<FilterRule>,
    },
    isLastFilter: {
      required: false,
      type: Boolean,
      default: true,
    },
    showType: {
      required: false,
      type: Boolean,
      default: true,
    },
    showAddRemove: {
      required: false,
      type: Boolean,
      default: true,
    },
  },
  emits: ["update:modelValue", "addFilter", "removeFilter"],
  setup() {
    const classesStore = useClassesStore();
    const stateStore = useStateStore();

    return {
      ClassSelectorColumn,
      classesStore,
      stateStore,
      TeachingType,
    };
  },
  data() {
    return {
      ruleset: this.modelValue,
    };
  },
  computed: {
    disableUpper(): number {
      return Math.floor(
        ((this.ruleset.filterData as Record<string, number>).endTime ??
          86400 * 7) / 86400,
      );
    },
    disableLower(): number {
      return Math.floor(
        ((this.ruleset.filterData as Record<string, number>).startTime ?? 0) /
          86400,
      );
    },
    searchPlaceholderText(): string {
      switch (this.ruleset.column) {
        case ClassSelectorColumn.Module:
          return "Suche nach Modulkürzel oder Name";
        case ClassSelectorColumn.Room:
          return "Suche nach Raumbezeichnung";
        case ClassSelectorColumn.Class:
          return "Suche nach Klassenbezeichnung";
        case ClassSelectorColumn.Lecturer:
          return "Suche nach Dozentenkürzel";
        case ClassSelectorColumn.Time:
          break;
      }

      return "";
    },
  },
  methods: {
    filterEnabledClick(direct: boolean) {
      if (!direct) {
        // Someone pressed the box around the checkbox.
        this.ruleset.enabled = !this.ruleset.enabled;
      } else {
        // Only notify changes when the value change is detected directly
        this.filterChanged();
      }
    },
    filterChanged() {
      this.$emit("update:modelValue", this.ruleset);
    },
    filterTypeChanged() {
      if (this.ruleset.column == ClassSelectorColumn.Degree) {
        if (!this.ruleset.filterData.degree)
          this.ruleset.filterData.degree = this.classesStore.degreePrograms[0];
      }
      if (this.ruleset.column == ClassSelectorColumn.TeachingType) {
        if (!this.ruleset.filterData.teachingType)
          this.ruleset.filterData.teachingType = "";
      }
    },
  },
};
</script>

<style scoped>
@reference "../../style.css";

.action-button {
  @apply h-5
    text-xs
    md:h-7
    md:text-base
    mx-0.5
    md:mx-1
    block
    bg-gray-200
    hover:bg-gray-300
    active:bg-gray-400
    disabled:bg-gray-200
    disabled:text-gray-400
    dark:bg-gray-700
    dark:hover:bg-gray-600
    dark:active:bg-gray-700
    dark:disabled:bg-gray-800
    dark:disabled:text-gray-600
    disabled:pointer-events-none
    aspect-square
    rounded-sm
    transition-all
    duration-200;
}
.action-checkbox {
  @apply h-5
    text-xs
    m-2
    md:h-7
    md:text-base
    mx-0.5
    md:mx-1
    bg-gray-200
    hover:bg-gray-300
    active:bg-gray-400
    disabled:bg-gray-200
    disabled:text-gray-400
    dark:bg-gray-700
    dark:hover:bg-gray-600
    dark:active:bg-gray-700
    dark:disabled:bg-gray-800
    dark:disabled:text-gray-600
    disabled:pointer-events-none
    aspect-square
    rounded-sm
    transition-all
    duration-200
    items-center
    flex
    cursor-pointer;
}
.action-checkbox input {
  @apply cursor-pointer;
}
</style>
