<script setup lang="ts">
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
import log from "loglevel";
import { useCourseData, useDashboardPersons } from "@/composables";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import { computed, ref, watch } from "vue";
import { useTranslation } from "i18next-vue";
import _ from "lodash";
import DueDatesList from "@/components/dueDates/DueDatesList.vue";

log.debug("DashboardPersonsPage created");

const UNFILTERED = Number.MAX_SAFE_INTEGER.toString();

type DropboxItem = {
  id: string;
  name: string;
};

type CourseItem = DropboxItem & {
  slug: string;
};

const { t } = useTranslation();

const { loading, dashboardDueDates } = useDashboardPersons();

const courses = computed(() => {
  return [
    {
      id: UNFILTERED,
      name: t("a.Alle Lehrgänge"),
      slug: "",
    },
    ..._(dashboardDueDates.value)
      .map((dueDate) => {
        return {
          name: dueDate.course_session.course_title,
          id: dueDate.course_session.course_id,
          slug: dueDate.course_session.course_slug,
        };
      })
      .uniqBy("id")
      .orderBy("name")
      .value(),
  ];
});

const selectedCourse = ref<CourseItem>(courses.value[0]);

const courseSessions = computed(() => {
  let sessions = _(dashboardDueDates.value)
    .map((dueDate) => {
      return Object.assign({}, dueDate.course_session, {
        name: dueDate.course_session.session_title,
        id: dueDate.course_session.id,
      });
    })
    .uniqBy("id")
    .orderBy("name")
    .value();

  // filter by selected course
  if (selectedCourse.value.id !== UNFILTERED) {
    sessions = sessions.filter((cs) => cs.course_id === selectedCourse.value.id);
  }

  return [
    {
      id: UNFILTERED,
      name: t("a.AlleDurchführungen"),
    },
    ...sessions,
  ];
});

const selectedSession = ref<DropboxItem>(courseSessions.value[0]);

const filteredDueDates = computed(() => {
  return _.orderBy(
    dashboardDueDates.value
      .filter((dueDate) => {
        if (selectedCourse.value.id === UNFILTERED) {
          return true;
        }
        return dueDate.course_session.course_id === selectedCourse.value.id;
      })
      .filter((dueDate) => {
        if (selectedSession.value.id === UNFILTERED) {
          return true;
        }
        return dueDate.course_session.id === selectedSession.value.id;
      })
      .filter((dueDate) => {
        if (selectedCircle.value.id === UNFILTERED) {
          return true;
        }
        return dueDate.circle?.id === selectedCircle.value.id;
      })
      .filter((dueDate) => {
        if (selectedType.value.id === UNFILTERED) {
          return true;
        }
        return dueDate.translatedType === selectedType.value.id;
      }),

    ["start"]
  );
});

const filtersVisible = computed(() => {
  return (
    courses.value.length > 2 ||
    courseSessions.value.length > 2 ||
    circles.value.length > 2 ||
    dueDateTypes.value.length > 2
  );
});

const initialItemCircle: DropboxItem = {
  id: UNFILTERED,
  name: t("a.AlleCircle"),
};
const circles = ref<DropboxItem[]>([initialItemCircle]);
const selectedCircle = ref<DropboxItem>(circles.value[0]);

async function loadCircleValues() {
  if (selectedCourse.value && selectedCourse.value.slug) {
    const learningPathQuery = useCourseData(selectedCourse.value.slug);
    await learningPathQuery.resultPromise;
    circles.value = [
      initialItemCircle,
      ...(learningPathQuery.circles.value ?? []).map((circle) => ({
        id: circle.id,
        name: circle.title,
      })),
    ];
  } else {
    circles.value = [initialItemCircle];
  }

  selectedCircle.value = circles.value[0];
}

const dueDateTypes = computed(() => {
  const types = _(dashboardDueDates.value)
    .map((dueDate) => {
      return {
        name: dueDate.translatedType,
        id: dueDate.translatedType,
      };
    })
    .uniqBy("id")
    .orderBy("name")
    .value();

  return [
    {
      id: UNFILTERED,
      name: t("a.AlleTypen"),
    },
    ...types,
  ];
});

const selectedType = ref<DropboxItem>(dueDateTypes.value[0]);

watch(selectedCourse, async () => {
  selectedSession.value = courseSessions.value[0];
  await loadCircleValues();
});
</script>

<template>
  <div>
    <div v-if="loading" class="m-8 flex justify-center">
      <LoadingSpinner />
    </div>
    <div v-else class="bg-gray-200">
      <div class="container-large">
        <router-link
          :to="`/`"
          class="btn-text inline-flex items-center p-0"
          data-cy="back-to-learning-path-button"
        >
          <it-icon-arrow-left class="-ml-1 mr-1 h-5 w-5"></it-icon-arrow-left>
          <span class="inline">{{ $t("general.back") }}</span>
        </router-link>

        <h2 class="my-4">{{ $t("a.Termine") }}</h2>
        <div class="bg-white px-4 py-2">
          <section
            v-if="filtersVisible"
            class="flex flex-col space-x-0 border-b bg-white lg:flex-row lg:space-x-3"
          >
            <ItDropdownSelect
              v-if="courses.length > 2"
              v-model="selectedCourse"
              data-cy="session-select"
              :items="courses"
              borderless
            ></ItDropdownSelect>

            <ItDropdownSelect
              v-if="courseSessions.length > 2"
              v-model="selectedSession"
              data-cy="session-select"
              :items="courseSessions"
              borderless
            ></ItDropdownSelect>

            <ItDropdownSelect
              v-if="circles.length > 2"
              v-model="selectedCircle"
              data-cy="appointments-circle-select"
              :items="circles"
              borderless
            ></ItDropdownSelect>

            <ItDropdownSelect
              v-if="dueDateTypes.length > 2"
              v-model="selectedType"
              data-cy="appointments-type-select"
              :items="dueDateTypes"
              borderless
            ></ItDropdownSelect>
          </section>

          <section>
            <DueDatesList
              :show-top-border="false"
              :show-bottom-border="false"
              :due-dates="filteredDueDates"
              :show-all-due-dates-link="false"
              :max-count="100"
              data-cy="due-date-list"
              :show-course-session="true"
            />
          </section>
        </div>
      </div>
    </div>
  </div>
</template>
