<script setup lang="ts">
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
import { useCourseSessionDetailQuery } from "@/composables";
import type { AttendanceUserStatus } from "@/gql/graphql";
import { ATTENDANCE_CHECK_MUTATION } from "@/graphql/mutations";
import type { DropdownSelectable } from "@/types";
import { useMutation } from "@urql/vue";
import dayjs from "dayjs";
import log from "loglevel";
import { computed, onMounted, reactive, watch } from "vue";
import { useTranslation } from "i18next-vue";
import { ATTENDANCE_CHECK_QUERY } from "@/graphql/queries";
import { graphqlClient } from "@/graphql/client";

const { t } = useTranslation();
const attendanceMutation = useMutation(ATTENDANCE_CHECK_MUTATION);
const courseSessionDetailResult = useCourseSessionDetailQuery();

const attendanceCourses = computed(() => {
  return courseSessionDetailResult.courseSessionDetail.value?.attendance_courses ?? [];
});

const courseSessionDetail = computed(() => {
  return courseSessionDetailResult.courseSessionDetail.value;
});

const presenceCoursesDropdownOptions = computed(() => {
  return attendanceCourses.value.map(
    (attendanceCourse) =>
      ({
        id: attendanceCourse.id,
        name: `${t("Präsenzkurs")} ${
          attendanceCourse.learning_content.circle.title
        } ${dayjs(attendanceCourse.due_date?.start).format("DD.MM.YYYY")}`,
      } as DropdownSelectable)
  );
});

const state = reactive({
  userPresence: new Map<string, boolean>(),
  attendanceCourseSelected: presenceCoursesDropdownOptions.value[0],
  disclaimerConfirmed: false,
  attendanceSaved: false,
});

watch(
  attendanceCourses,
  (newVal) => {
    if (newVal && newVal.length > 0) {
      state.attendanceCourseSelected = presenceCoursesDropdownOptions.value[0];
    }
  },
  { immediate: true }
);

function resetState() {
  state.userPresence = new Map<string, boolean>();
  state.disclaimerConfirmed = false;
  state.attendanceSaved = false;
}

const onSubmit = async () => {
  type UserPresence = {
    user_id: string;
    status: AttendanceUserStatus;
  };
  const attendanceUserList: UserPresence[] = Array.from(state.userPresence.keys()).map(
    (key) => ({
      user_id: key,
      status: state.userPresence.get(key) ? "PRESENT" : "ABSENT",
    })
  );
  const res = await attendanceMutation.executeMutation({
    attendanceCourseId: state.attendanceCourseSelected.id.toString(),
    attendanceUserList: attendanceUserList,
  });
  if (res.error) {
    log.error("Could not submit attendance check: ", res.error);
    return;
  }
  state.disclaimerConfirmed = false;
  state.attendanceSaved = true;
  log.info("Attendance check submitted: ", res);
};

const loadAttendanceData = async () => {
  resetState();
  // with changing variables `useQuery` does not seem to work correctly
  if (state.attendanceCourseSelected) {
    const res = await graphqlClient.query(
      ATTENDANCE_CHECK_QUERY,
      {
        courseSessionId: state.attendanceCourseSelected.id.toString(),
      },
      {
        requestPolicy: "network-only",
      }
    );
    const attendanceUserList =
      res.data?.course_session_attendance_course?.attendance_user_list ?? [];
    for (const user of attendanceUserList) {
      if (!user) continue;
      state.userPresence.set(user.user_id, user.status === "PRESENT");
    }
    if (attendanceUserList.length !== 0) {
      state.attendanceSaved = true;
    }
  }
};

function editAgain() {
  state.attendanceSaved = false;
}

onMounted(() => {
  log.debug("AttendanceCheckPage mounted");
  loadAttendanceData();
});

watch(
  () => state.attendanceCourseSelected,
  () => {
    log.debug("attendanceCourseSelected changed", state.attendanceCourseSelected);
    loadAttendanceData();
  },
  { immediate: true }
);
</script>

<template>
  <div class="bg-gray-200">
    <div v-if="courseSessionDetail" class="container-large">
      <nav class="py-4 pb-4">
        <router-link
          class="btn-text inline-flex items-center pl-0"
          :to="`/course/${courseSessionDetail.course.slug}/cockpit`"
        >
          <it-icon-arrow-left />
          <span>{{ $t("general.back") }}</span>
        </router-link>
      </nav>
      <div class="pb-4 text-xl font-bold">{{ $t("Anwesenheit Präsenzkurse") }}</div>

      <section v-if="attendanceCourses.length && state.attendanceCourseSelected">
        <div class="flex flex-row justify-between bg-white p-6">
          <ItDropdownSelect
            v-model="state.attendanceCourseSelected"
            :items="presenceCoursesDropdownOptions ?? []"
          ></ItDropdownSelect>
          <div v-if="!state.attendanceSaved" class="flex flex-row items-center">
            <ItCheckbox
              :checkbox-item="{
                value: true,
                checked: state.disclaimerConfirmed,
              }"
              @toggle="state.disclaimerConfirmed = !state.disclaimerConfirmed"
            ></ItCheckbox>
            <p class="w-64 pr-4 text-sm">
              {{
                $t(
                  "Ich will die Anwesenheit der untenstehenden Personen definitiv bestätigen."
                )
              }}
            </p>
            <button
              class="btn-primary"
              :disabled="!state.disclaimerConfirmed"
              @click="onSubmit"
            >
              {{ $t("Anwesenheit bestätigen") }}
            </button>
          </div>
          <div v-else class="self-center">
            <p class="text-base">
              {{ $t("a.Die Anwesenheit wurde definitiv bestätigt") }}
            </p>
            <button class="btn-link link" @click="editAgain()">
              {{ $t("a.Erneut bearbeiten") }}
            </button>
          </div>
        </div>

        <div class="mt-4 flex flex-col bg-white p-6">
          <div
            v-for="(csu, index) in courseSessionDetailResult.filterMembers()"
            :key="csu.user_id"
          >
            <ItPersonRow
              :name="`${csu.first_name} ${csu.last_name}`"
              :avatar-url="csu.avatar_url"
              :class="0 === index ? 'border-none' : ''"
            >
              <template #leading>
                <ItCheckbox
                  :disabled="state.attendanceSaved"
                  :checkbox-item="{
                  value: true,
                  checked: state.userPresence.get(csu.user_id) as boolean,
                }"
                  @toggle="
                    state.userPresence.set(
                      csu.user_id,
                      !state.userPresence.get(csu.user_id)
                    )
                  "
                ></ItCheckbox>
              </template>
            </ItPersonRow>
          </div>
        </div>
      </section>
    </div>
  </div>
</template>
