<script setup lang="ts">
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
import ItTextarea from "@/components/ui/ItTextarea.vue";
import RichText from "@/components/ui/RichText.vue";
import { useCurrentCourseSession } from "@/composables";
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
import {
  maxAssignmentPoints,
  userAssignmentPoints,
} from "@/services/assignmentService";
import type {
  Assignment,
  AssignmentCompletion,
  AssignmentEvaluationTask,
  CourseSessionUser,
} from "@/types";
import { useMutation } from "@urql/vue";
import dayjs, { Dayjs } from "dayjs";
import * as log from "loglevel";
import { computed, reactive, ref } from "vue";

const props = defineProps<{
  assignmentUser: CourseSessionUser;
  assignment: Assignment;
  assignmentCompletion: AssignmentCompletion;
  showEvaluationUser?: boolean;
  dueDate?: Dayjs;
}>();

const emit = defineEmits(["editTask"]);

const state = reactive({
  showSuccessInfo: false,
});

log.debug("EvaluationSummary setup");

const courseSession = useCurrentCourseSession();

const upsertAssignmentCompletionMutation = useMutation(
  UPSERT_ASSIGNMENT_COMPLETION_MUTATION
);

const evaluationComment = ref(
  props.assignmentCompletion.completion_data.expert_evaluation_comment?.text ?? ""
);

const text = computed(() => {
  if (props.assignment.assignment_type === "CASEWORK") {
    return {
      evaluationCriteria: "a.Beurteilungskriterium",
      evaluationReason: "assignment.evaluationReason",
      evaluationSubmit: "a.Bewertung freigeben",
      evaluationSubmission: "a.Bewertung Freigabe",
      evaluationFromUser: "a.Bewertung von x y",
      evaluationSuccess: "a.Deine Bewertung für x y wurde freigegeben.",
    };
  } else if (props.assignment.assignment_type === "PRAXIS_ASSIGNMENT") {
    return {
      evaluationCriteria: "Feedback",
      evaluationReason: "assignment.evaluationFeedback",
      evaluationSubmit: "a.Feedback freigeben",
      evaluationSubmission: "a.Feedback Freigabe",
      evaluationFromUser: "a.Feedback von x y",
      evaluationSuccess: "a.Dein Feedback für x y wurde freigegeben.",
    };
  } else {
    return {
      evaluationCriteria: "UNKNOWN ASSIGNMENT TYPE",
      evaluationReason: "UNKNOWN ASSIGNMENT TYPE",
      evaluationSubmit: "UNKNOWN ASSIGNMENT TYPE",
      evaluationSubmission: "UNKNOWN ASSIGNMENT TYPE",
      evaluationFromUser: "UNKNOWN ASSIGNMENT TYPE",
      evaluationSuccess: "UNKNOWN ASSIGNMENT TYPE",
    };
  }
});

async function submitEvaluation() {
  upsertAssignmentCompletionMutation.executeMutation({
    assignmentId: props.assignment.id,
    courseSessionId: courseSession.value.id,
    assignmentUserId: props.assignmentUser.id,
    completionStatus: "EVALUATION_SUBMITTED",
    completionDataString: JSON.stringify({
      expert_evaluation_comment: {
        text: evaluationComment.value,
      },
    }),
    evaluationPoints: userPoints.value,
    // next line used for urql
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    id: props.assignmentCompletion?.id,
  });
  log.debug("submitEvaluation");
  state.showSuccessInfo = true;
}

function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
  return task.value.sub_tasks !== undefined
    ? task.value.sub_tasks.find((subTask) => subTask.value.points === points)
    : null;
}

function evaluationForTask(task: AssignmentEvaluationTask) {
  const expertData = props.assignmentCompletion.completion_data[task.id]?.expert_data;
  if (!expertData) {
    return {
      points: 0,
      text: "",
    };
  }

  return expertData;
}

const maxPoints = computed(() => {
  if (props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED") {
    return props.assignmentCompletion.evaluation_max_points;
  }
  return maxAssignmentPoints(props.assignment);
});

const userPoints = computed(() =>
  userAssignmentPoints(props.assignment, props.assignmentCompletion)
);

const userPointsWithDeduction = computed(() => {
  const points = userPoints.value;
  if (points && props.assignmentCompletion.evaluation_points_deducted > 0) {
    return points - props.assignmentCompletion.evaluation_points_deducted;
  }
  return points;
});

const percentage = computed(() => {
  if (props.assignmentCompletion.completion_status === "EVALUATION_SUBMITTED") {
    return (
      ((props.assignmentCompletion?.evaluation_points_final ??
        userPointsWithDeduction.value ??
        0) /
        (props.assignmentCompletion?.evaluation_max_points ?? 1)) *
      100
    );
  } else {
    return ((userPointsWithDeduction.value ?? 0) / (maxPoints.value ?? 1)) * 100;
  }
});

const showNotPassed = computed(() => {
  if (props.assignment.assignment_type === "CASEWORK") {
    return percentage.value < 55;
  }

  return false;
});

const showPassed = computed(() => {
  if (props.assignment.assignment_type === "CASEWORK") {
    return percentage.value >= 55;
  }

  return false;
});
</script>

<template>
  <!-- eslint-disable vue/no-v-html -->
  <div>
    <h3
      v-if="assignmentCompletion.evaluation_user && props.showEvaluationUser"
      class="mb-6"
    >
      {{
        $t(text.evaluationFromUser, {
          x: assignmentCompletion.evaluation_user.first_name,
          y: assignmentCompletion.evaluation_user.last_name,
        })
      }}
    </h3>
    <h3 v-else class="mb-6" data-cy="sub-title">{{ $t(text.evaluationSubmission) }}</h3>
    <section class="mb-6 border p-6" data-cy="result-section">
      <section v-if="props.assignment.assignment_type === 'CASEWORK'">
        <div class="flex items-center">
          <div class="heading-1 py-4" data-cy="user-points">
            {{ userPointsWithDeduction }}
          </div>
          <div class="pl-2" data-cy="total-points">
            {{ $t("assignment.von x Punkten", { x: maxPoints }) }}
            ({{ percentage.toFixed(0) }}%)
          </div>

          <div v-if="showNotPassed" class="ml-2">
            <span class="my-2 rounded-md bg-error-red-200 px-2.5 py-0.5">
              {{ $t("a.Nicht Bestanden") }}
            </span>
          </div>

          <div v-if="showPassed" class="ml-2">
            <span class="my-2 rounded-md bg-green-200 px-2.5 py-0.5">
              {{ $t("a.Bestanden") }}
            </span>
          </div>
        </div>

        <div
          v-if="assignmentCompletion.evaluation_points_deducted > 0"
          data-cy="points-deducted"
          class="mb-4 text-gray-900"
        >
          <div>
            {{ $t("a.Punkte aus Bewertung") }}:
            {{ assignmentCompletion.evaluation_points }}
          </div>
          <div>
            {{ $t("a.Abgezogene Punkte") }}:
            {{ assignmentCompletion.evaluation_points_deducted }}
          </div>
          <div>
            {{ $t("a.Grund") }}:
            {{ assignmentCompletion.evaluation_points_deducted_reason }}
          </div>
        </div>
      </section>

      <div
        v-if="
          props.assignment.assignment_type === 'CASEWORK' &&
          props.assignmentCompletion.completion_status === 'EVALUATION_SUBMITTED' &&
          !props.assignmentCompletion.evaluation_passed
        "
      >
        <span class="my-2 rounded-md bg-error-red-200 px-2.5 py-0.5">
          {{ $t("a.Nicht bestanden") }}
        </span>
      </div>

      <div v-if="props.assignment.assignment_type === 'CASEWORK'">
        <p class="my-4">
          {{ $t("assignment.evaluationInstrumentDescriptionText") }}
        </p>
        <p class="my-4">
          <a
            :href="props.assignment.evaluation_document_url"
            class="link"
            target="_blank"
          >
            {{ $t("a.Beurteilungsinstrument anzeigen") }}
          </a>
        </p>
      </div>

      <p v-if="props.dueDate" class="my-4" data-cy="evaluation-duedate">
        {{ "a.Freigabetermin Bewertung" }}: {{ props.dueDate.format("DD.MM.YYYY") }}
        {{ props.dueDate.format("HH.mm") }}
      </p>

      <p
        v-if="
          props.assignment.assignment_type === 'PRAXIS_ASSIGNMENT' &&
          props.assignmentCompletion.completion_status !== 'EVALUATION_SUBMITTED'
        "
      >
        {{ $t("a.assignment.evaluationFeedbackDescriptionText") }}
      </p>

      <section>
        <div
          v-for="historyEntry in props.assignmentCompletion.additional_json_data
            ?.submission_history ?? []"
          :key="historyEntry.timestamp"
        >
          {{ dayjs(historyEntry.timestamp).format("DD.MM.YYYY HH.mm") }}:
          {{ $t(historyEntry.translation_key) }}
          ({{ historyEntry.user_display_name }})
        </div>
      </section>

      <div
        v-if="props.assignmentCompletion.completion_status !== 'EVALUATION_SUBMITTED'"
        class="mt-8"
      >
        <button
          class="btn-primary text-large"
          data-cy="submit-evaluation"
          @click="submitEvaluation()"
        >
          {{ $t(text.evaluationSubmit) }}
        </button>

        <ItTextarea
          v-model="evaluationComment"
          class="mt-8"
          :placeholder="`${$t('a.Kommentar erfassen')}...`"
          data-cy="reason-text"
        ></ItTextarea>
      </div>
      <div v-else-if="evaluationComment" class="mt-4">
        {{ evaluationComment }}
      </div>

      <div v-if="state.showSuccessInfo" class="mt-4">
        <ItSuccessAlert
          :text="
            $t(text.evaluationSuccess, {
              x: props.assignmentUser.first_name,
              y: props.assignmentUser.last_name,
            })
          "
        ></ItSuccessAlert>
      </div>
    </section>

    <section>
      <div v-for="(task, index) in props.assignment.evaluation_tasks" :key="task.id">
        <article class="border-t py-4">
          <div class="flex flex-row justify-between">
            <div class="mb-4 text-gray-900">
              {{ $t(text.evaluationCriteria) }} {{ index + 1 }}:
              {{ task.value.title }}
            </div>
            <div
              v-if="
                props.assignmentCompletion.completion_status !== 'EVALUATION_SUBMITTED'
              "
            >
              <button
                class="link pl-2text-sm whitespace-nowrap"
                @click="emit('editTask', task)"
              >
                {{ $t("assignment.edit") }}
              </button>
            </div>
          </div>

          <RichText
            class="mb-2 font-bold"
            :content="task.value.description"
            open-links-in-new-tab
          />

          <section class="mb-4">
            <div
              v-html="
                subTaskByPoints(task, evaluationForTask(task).points)?.value.title
              "
            ></div>

            <RichText
              :content="
                subTaskByPoints(task, evaluationForTask(task).points)?.value.description
              "
              open-links-in-new-tab
            />

            <div
              v-if="assignment.assignment_type === 'CASEWORK'"
              class="text-sm text-gray-800"
            >
              {{ evaluationForTask(task).points }} Punkte
            </div>
          </section>

          <div>
            <span class="font-bold">{{ $t(text.evaluationReason) }}:</span>
            {{ evaluationForTask(task).text }}
          </div>
        </article>
      </div>
    </section>
  </div>
</template>

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