<script setup lang="ts">
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
import type {
  AttendanceUserStatus,
  CourseSessionAttendanceCourseObjectType,
} from "@/gql/graphql";
import { ATTENDANCE_CHECK_MUTATION } from "@/graphql/mutations";
import { ATTENDANCE_CHECK_QUERY } from "@/graphql/queries";
import { exportAttendance } from "@/services/dashboard";
import { useExpertCockpitStore } from "@/stores/expertCockpit";
import { useUserStore } from "@/stores/user";
import { openDataAsXls } from "@/utils/export";
import { useMutation, useQuery } from "@urql/vue";
import { useDateFormat } from "@vueuse/core";
import { useTranslation } from "i18next-vue";
import log from "loglevel";
import { computed, onMounted, ref } from "vue";
import AttendanceCheck from "../cockpitPage/AttendanceCheck.vue";
import AttendanceStatus from "../cockpitPage/AttendanceStatus.vue";

const attendanceMutation = useMutation(ATTENDANCE_CHECK_MUTATION);
const courseSessionDetailResult = useCourseSessionDetailQuery();
const userStore = useUserStore();
const courseSession = useCurrentCourseSession();
const expertCockpitStore = useExpertCockpitStore();

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

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

const currentCourse = computed(() => expertCockpitStore.currentCourse);

const userPresence = ref(new Map<string, boolean>());
const disclaimerConfirmed = ref(false);
const attendanceSaved = ref(false);

const { t } = useTranslation();

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

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

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

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

const toggleDisclaimer = (newValue: boolean) => {
  disclaimerConfirmed.value = newValue;
};

async function exportData() {
  const data = await exportAttendance(
    {
      courseSessionIds: [Number(courseSession.value.id)],
      circleIds: [Number(currentCourse.value?.learning_content.circle?.id)],
    },
    userStore.language
  );
  openDataAsXls(data.encoded_data, data.file_name);
}

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

const courseDueDate = computed(() => {
  if (currentCourse.value && currentCourse.value.due_date?.start) {
    return currentCourse.value.due_date.start;
  }
  return "";
});

const formattedCourseDueDate = computed(() => {
  if (courseDueDate.value) {
    return useDateFormat(courseDueDate.value, "D. MMMM YYYY", {
      locales: "de-CH",
    });
  }
  return "";
});
</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="flex items-center justify-between"></div>
      <section v-if="attendanceCourses.length && currentCourse">
        <div class="grid grid-cols-[2fr_1fr] justify-between gap-8 bg-white py-6">
          <div class="col-span-1 flex flex-col gap-2 px-6">
            <h3 class="pb-1 text-4xl font-bold">{{ $t("a.Präsenzkurs") }}</h3>
            <h5>
              {{ t("a.Circle") }} «{{ currentCourse?.learning_content.circle?.title }}»
            </h5>
            <h5>{{ formattedCourseDueDate }}</h5>
          </div>
          <button
            v-if="attendanceSaved"
            class="col-span-1 mr-4 hidden justify-self-end lg:flex"
            data-cy="export-button"
            @click="exportData"
          >
            <it-icon-export class="fill-current text-blue-900"></it-icon-export>
            <span class="ml inline-block text-blue-900">
              {{ $t("a.Als Excel exportieren") }}
            </span>
          </button>
          <div
            class="col-span-2 flex flex-col items-start gap-4 px-6 lg:gap-6"
            :class="attendanceSaved ? 'lg:flex-row lg:items-center' : 'gap-8 lg:gap-8'"
          >
            <AttendanceStatus
              class="inline-flex px-6"
              :done="attendanceSaved"
              :date="courseDueDate"
            />

            <AttendanceCheck
              :attendance-saved="attendanceSaved"
              :disclaimer-confirmed="disclaimerConfirmed"
              @reopen="editAgain"
              @toggle="toggleDisclaimer"
              @confirm="onSubmit"
            />
          </div>

          <div class="col-span-2 border-t border-gray-500 px-6">
            <ItPersonRow
              v-for="(csu, index) in courseSessionDetailResult.filterMembers()"
              :key="csu.user_id"
              :name="`${csu.first_name} ${csu.last_name}`"
              :avatar-url="csu.avatar_url"
              :class="0 === index ? 'border-none' : ''"
              :extra-info="
                csu.optional_attendance ? `${$t('a.Optionale Anwesenheit')}` : ''
              "
            >
              <template #leading>
                <ItCheckbox
                  :disabled="attendanceSaved"
                  :checkbox-item="{
                    value: true,
                    checked: userPresence.get(csu.user_id) as boolean,
                  }"
                  @toggle="
                    userPresence.set(csu.user_id, !userPresence.get(csu.user_id))
                  "
                ></ItCheckbox>
              </template>
            </ItPersonRow>
          </div>
        </div>
      </section>
    </div>
  </div>
</template>
