<script setup lang="ts">
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import ItTextarea from "@/components/ui/ItTextarea.vue";
import { useCurrentCourseSession } from "@/composables";
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
import type {
  AssignmentCompletion,
  AssignmentCompletionData,
  AssignmentTask,
  UserDataConfirmation,
  UserDataText,
} from "@/types";
import { useMutation } from "@urql/vue";
import { useDebounceFn } from "@vueuse/core";
import log from "loglevel";
import { computed, reactive } from "vue";

const props = defineProps<{
  assignmentId: number;
  task: AssignmentTask;
  assignmentCompletion?: AssignmentCompletion;
}>();

const checkboxState = reactive({} as Record<string, boolean>);

const courseSession = useCurrentCourseSession();

const upsertAssignmentCompletionMutation = useMutation(
  UPSERT_ASSIGNMENT_COMPLETION_MUTATION
);

async function upsertAssignmentCompletion(completion_data: AssignmentCompletionData) {
  try {
    // noinspection TypeScriptValidateTypes
    await upsertAssignmentCompletionMutation.executeMutation({
      assignmentId: props.assignmentId.toString(),
      courseSessionId: courseSession.value.id.toString(),
      completionDataString: JSON.stringify(completion_data),
      completionStatus: "IN_PROGRESS",
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      id: props.assignmentCompletion?.id,
    });
    log.debug("Saved user input");
  } catch (error) {
    log.error("Could not save user input", error);
  }
}

const upsertAssignmentCompletionDebounced = useDebounceFn(
  upsertAssignmentCompletion,
  500
);

function getCompletionDataForUserInput(id: string) {
  return props.assignmentCompletion?.completion_data[id];
}

const onUpdateText = (id: string, value: string) => {
  const data: AssignmentCompletionData = {};
  data[id] = {
    user_data: {
      text: value,
    } as UserDataText,
  };
  upsertAssignmentCompletionDebounced(data);
};

const onUpdateConfirmation = (id: string, value: boolean) => {
  const data: AssignmentCompletionData = {};
  data[id] = {
    user_data: {
      confirmation: value,
    } as UserDataConfirmation,
  };
  upsertAssignmentCompletion(data);
};

const getBlockData = (id: string) => {
  const userData = getCompletionDataForUserInput(id)?.user_data;
  if (userData && "text" in userData) {
    return userData.text;
  } else if (userData && "confirmation" in userData) {
    return userData.confirmation;
  }
  return null;
};

const onToggleCheckbox = (id: string) => {
  checkboxState[id] = !checkboxState[id];
  onUpdateConfirmation(id, checkboxState[id]);
};

const completionStatus = computed(() => {
  return props.assignmentCompletion?.completion_status ?? "IN_PROGRESS";
});
</script>

<template>
  <!-- eslint-disable vue/no-v-html -->
  <div class="flex flex-col space-y-10">
    <div v-for="(block, index) in props.task.value.content" :key="block.id">
      <div v-if="block.type === 'explanation'">
        <p class="default-wagtail-rich-text text-large" v-html="block.value.text"></p>
      </div>

      <div v-if="block.type === 'user_confirmation'">
        <ItCheckbox
          :checkbox-item="{
            label: block.value.text,
            value: `confirmation-${index}`,
            checked: getBlockData(block.id) as boolean,
          }"
          :disabled="completionStatus !== 'IN_PROGRESS'"
          @toggle="onToggleCheckbox(block.id)"
        ></ItCheckbox>
      </div>
      <div v-if="block.type === 'user_text_input'">
        <p
          v-if="block.value.text"
          class="text-large pb-4"
          v-html="block.value.text"
        ></p>
        <ItTextarea
          class="w-[300px] sm:w-[600px]"
          :model-value="(getBlockData(block.id) as string) ?? ''"
          :cy-key="`user-text-input-${index}`"
          :disabled="completionStatus !== 'IN_PROGRESS'"
          label=""
          @update:model-value="onUpdateText(block.id, $event)"
        ></ItTextarea>
      </div>
    </div>
  </div>

  <div v-if="props.task.value.file_submission_required">
    <p class="text-large">Datei hochladen</p>

    <p class="text-sm text-gray-900">
      Mögliche Formate: .JPG, .PNG, .PDF, .DOC, .MOV, .PPT
    </p>
  </div>
</template>
