<template>
  <div class="ste">
    <div class="ste__header">
      <BoxedIconTitleBlock
        class="exam-form__heading"
        :title="exam?.title"
        desc="لطفا سوالات به دقت خوانده و جواب درست را علامت بزنید"
      >
        <template #icon>
          <SvgIcon name="pencil" :size="24" color="var(--color-primary)" />
        </template>
      </BoxedIconTitleBlock>

      <div class="ste__timer">
        <span class="ste__timer-label">زمان باقی مانده :</span>
        <span class="ste__timer-value">{{ timerText }}</span>
      </div>
    </div>

    <SkeletonLoaderBlock v-if="isLoading && !exam" :rows="3" :cols-per-row="2" />

    <div v-else class="ste__body">
      <div class="ste__questions">
        <StudentExamQuestion
          v-for="(question, index) in questions"
          :key="question.id"
          :question="question"
          :order="index + 1"
          :model-value="answers[question.id] ?? null"
          @update:model-value="(value) => onAnswer(question.id, value)"
        />
      </div>

      <div class="ste__actions">
        <BaseButton
          text="اتمام آزمون"
          :loading="submitMutation.isPending.value"
          custom-class="ste__submit"
          @click="onSubmit"
        >
          <template #appendIcon>
            <SvgIcon name="arrow-left" :size="18" color="#fff" />
          </template>
        </BaseButton>
      </div>
    </div>
  </div>
</template>

<script setup>
import { toast } from 'vue3-toastify'
import { useRoute, useRouter } from 'vue-router'
import BaseButton from '@/components/BaseButton.vue'
import SvgIcon from '@/components/icons/SvgIcon.vue'
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import SkeletonLoaderBlock from '@/components/blocks/SkeletonLoaderBlock.vue'
import BoxedIconTitleBlock from '@/components/blocks/BoxedIconTitleBlock.vue'
import StudentExamQuestion from '@/features/student/exams/components/StudentExamQuestion.vue'
import {
  useStartStudentExamMutation,
  useStudentExamQuery,
  useSubmitStudentExamAttemptMutation,
} from '@/services/query/student-exams'

const route = useRoute()
const router = useRouter()

const examId = computed(() => route.params.id)

const { data: exam, isLoading } = useStudentExamQuery(examId, {
  enabled: () => !!examId.value,
})

const questions = computed(() => exam.value?.questions ?? [])

const answers = reactive({})

const onAnswer = (questionId, value) => {
  if (value === null || value === undefined) delete answers[questionId]
  else answers[questionId] = value
}

const startMutation = useStartStudentExamMutation()
const remaining = ref(0)
let intervalId = null

const tickFrom = (seconds) => {
  if (intervalId) clearInterval(intervalId)
  remaining.value = Math.max(0, Math.floor(seconds))
  intervalId = setInterval(() => {
    if (remaining.value <= 0) {
      clearInterval(intervalId)
      intervalId = null
      onTimeout()
      return
    }
    remaining.value -= 1
  }, 1000)
}

// Begin (or resume) the attempt; the server returns deadlineAt which drives the
// countdown. Falls back to the exam duration if no deadline comes back.
const beginAttempt = async () => {
  try {
    const res = await startMutation.mutateAsync(examId.value)
    const attempt = res?.data ?? res
    const deadlineMs = attempt?.deadlineAt ? new Date(attempt.deadlineAt).getTime() : null
    if (deadlineMs) tickFrom((deadlineMs - Date.now()) / 1000)
    else if (exam.value?.durationMinutes != null) tickFrom(exam.value.durationMinutes * 60)
  } catch (error) {
    toast.error(error?.response?.data?.message || 'امکان شروع آزمون وجود ندارد.')
    router.push({ name: 'student-exam', params: { id: examId.value } }).catch(() => {})
  }
}

onBeforeUnmount(() => {
  if (intervalId) clearInterval(intervalId)
})

const pad = (n) => String(n).padStart(2, '0')
const timerText = computed(() => {
  const total = remaining.value
  const h = Math.floor(total / 3600)
  const m = Math.floor((total % 3600) / 60)
  const s = total % 60
  return h > 0 ? `${pad(h)}:${pad(m)}:${pad(s)}` : `${pad(m)}:${pad(s)}`
})

const submitMutation = useSubmitStudentExamAttemptMutation()

const submit = async () => {
  try {
    const payload = {
      answers: Object.entries(answers).map(([questionId, selectedOptionId]) => ({
        questionId: Number(questionId),
        selectedOptionId,
      })),
    }
    await submitMutation.mutateAsync({ id: examId.value, payload })
    toast.success('پاسخ‌های شما با موفقیت ثبت شد.')
    router.push({ name: 'student-exam', params: { id: examId.value } })
  } catch {
    toast.error('ثبت پاسخ‌ها با خطا مواجه شد.')
  }
}

const onSubmit = () => {
  if (Object.keys(answers).length === 0) {
    toast.warning('حداقل به یک سوال پاسخ دهید.')
    return
  }
  submit()
}

const onTimeout = () => {
  toast.info('زمان آزمون به پایان رسید.')
  submit()
}

onMounted(() => {
  if (!examId.value) {
    router.push({ name: 'student-dashboard' })
    return
  }
  beginAttempt()
})
</script>

<style lang="scss" scoped>
.ste {
  display: flex;
  flex-direction: column;
  gap: 1rem;

  &__header {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    border-radius: 0.75rem;

    @media (min-width: 768px) {
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
    }
  }

  &__heading {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
    text-align: end;
  }

  &__title {
    font-family: var(--font-family-fa);
    font-weight: 500;
    font-size: 1.125rem;
    color: #4b4b4b;
    margin: 0;
  }

  &__subtitle {
    font-family: var(--font-family-fa);
    font-weight: 300;
    font-size: 0.8125rem;
    color: #8c8c8c;
    margin: 0;
  }

  &__timer {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.875rem;
    border-radius: 0.75rem;
    background: rgba(245, 93, 109, 8%);
    align-self: flex-end;
    font-family: var(--font-family-fa);
    white-space: nowrap;

    @media (min-width: 768px) {
      align-self: center;
    }
  }

  &__timer-label {
    font-weight: 400;
    font-size: 0.75rem;
    color: #f55d6d;
  }

  &__timer-value {
    font-family: var(--font-family-en);
    font-weight: 500;
    font-size: 0.875rem;
    color: #f55d6d;
    direction: ltr;
  }

  &__body {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1.25rem 1.5rem;
    border-radius: 0.75rem;
  }

  &__questions {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem 2rem;

    @media (min-width: 768px) {
      grid-template-columns: 1fr 1fr;
    }
  }

  &__actions {
    display: flex;
    justify-content: flex-end;
    padding-top: 1rem;
    border-top: 1px solid var(--color-thd-gray);
  }

  &__submit {
    min-width: 14rem;
    padding: 0 2rem;
    height: 2.25rem;
  }
}
</style>
