<script setup lang="ts">
import ItTextarea from "@/components/ui/ItTextarea.vue";
import { useCurrentCourseSession } from "@/composables";
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
import type {
  Assignment,
  AssignmentCompletion,
  AssignmentCompletionData,
  CourseSessionUser,
  ExpertData,
} from "@/types";
import { useMutation } from "@urql/vue";
import { useDebounceFn } from "@vueuse/core";
import * as log from "loglevel";
import { computed } from "vue";

const props = defineProps<{
  assignmentUser: CourseSessionUser;
  assignment: Assignment;
  assignmentCompletion: AssignmentCompletion;
  taskIndex: number;
  allowEdit: boolean;
}>();

log.debug("EvaluationTask setup", props.taskIndex);

const courseSession = useCurrentCourseSession();

const task = computed(() => props.assignment.evaluation_tasks[props.taskIndex]);

const expertData = computed(() => {
  const data = (props.assignmentCompletion?.completion_data?.[task.value.id]
    ?.expert_data ?? {
    points: 0,
    text: "",
  }) as ExpertData;
  return data;
});

function changePoints(points: number) {
  log.debug("changePoints", points);
  evaluateAssignmentCompletion({
    [task.value.id]: {
      expert_data: { points, text: expertData.value.text },
    },
  });
}

function onUpdateText(value: string) {
  // log.debug("onUpdateText", value);
  evaluateAssignmentCompletionDebounced({
    [task.value.id]: {
      expert_data: {
        text: value,
        points: expertData.value.points,
      },
    },
  });
}

const upsertAssignmentCompletionMutation = useMutation(
  UPSERT_ASSIGNMENT_COMPLETION_MUTATION
);

async function evaluateAssignmentCompletion(completionData: AssignmentCompletionData) {
  log.debug("evaluateAssignmentCompletion", completionData);

  // noinspection TypeScriptValidateTypes
  upsertAssignmentCompletionMutation.executeMutation({
    assignmentId: props.assignment.id.toString(),
    courseSessionId: courseSession.value.id.toString(),
    assignmentUserId: props.assignmentUser.user_id.toString(),
    completionStatus: "EVALUATION_IN_PROGRESS",
    completionDataString: JSON.stringify(completionData),
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    id: props.assignmentCompletion?.id,
  });
}

const evaluateAssignmentCompletionDebounced = useDebounceFn(
  evaluateAssignmentCompletion,
  300
);
</script>

<template>
  <!-- eslint-disable vue/no-v-html -->
  <div data-cy="evaluation-task">
    <div class="text-bold mb-4 text-sm">
      Beurteilungskriterium {{ taskIndex + 1 }} /
      {{ props.assignment.evaluation_tasks.length }}
      {{ task.value.title }}
    </div>

    <h3 class="default-wagtail-rich-text mb-8" v-html="task.value.description"></h3>

    <fieldset>
      <div>
        <div
          v-for="(subTask, index) in task.value.sub_tasks"
          :key="index"
          class="mb-4 flex items-center last:mb-0"
          :data-cy="`subtask-${subTask.value.points}`"
        >
          <input
            :id="String(index)"
            name="coursesessions"
            type="radio"
            :value="subTask.value.points"
            :checked="expertData.points === subTask.value.points"
            :disabled="!props.allowEdit"
            class="focus:ring-indigo-900 h-4 w-4 border-gray-300 text-blue-900"
            @change="changePoints(subTask.value.points)"
          />
          <label :for="String(index)" class="ml-4 block">
            <div>{{ subTask.value.title }}</div>
            <div
              v-if="subTask.value.description"
              class="default-wagtail-rich-text"
              v-html="subTask.value.description"
            ></div>
            <div class="text-sm text-gray-800">{{ subTask.value.points }} Punkte</div>
          </label>
        </div>
      </div>
    </fieldset>
    <ItTextarea
      class="mt-8"
      :model-value="expertData.text ?? ''"
      label="Begründung"
      :disabled="!props.allowEdit"
      placeholder="Hier muss zwingend eine Begründung erfasst werden."
      data-cy="reason-text"
      @update:model-value="onUpdateText($event)"
    ></ItTextarea>
  </div>
</template>

<style lang="scss" scoped></style>
