<template lang="pug">
  v-container.fill-height.justify-center.pa-4.review-view-container
    v-fade-transition(mode="out-in")
      .d-flex.flex-column.justify-center.align-center.fill-height(v-if="loading")
        v-progress-circular(indeterminate color="primary" size="64")
        .text-body-1.text-grey.mt-4
          ScrambleText(:text="$t('review.loading')")

      v-card.pa-6.rounded-xl.d-flex.flex-column.align-center.review-card(
        v-else-if="currentItem"
      )
        .d-flex.align-center.w-100.mb-6
          v-btn.mr-2(
            icon="mdi-arrow-left"
            variant="text"
            color="grey"
            to="/"
            density="comfortable"
          )
          .text-caption.text-grey.font-weight-bold
            | {{ sessionDone }} / {{ sessionTotal }}
          v-spacer
          v-chip.font-weight-bold(
            size="small"
            :color="getSRSColor(currentItem.srsLevel)"
            variant="flat"
          )
            ScrambleText(:text="$t('review.level') + ' ' + currentItem.srsLevel")

        .text-center.mb-6
          .text-caption.text-grey.text-uppercase.tracking-wide.mb-1
            ScrambleText(:text="$t('review.meaning')")
          .text-h3.font-weight-bold.text-white.text-shadow.mb-4
            | {{ currentItem.meaning }}
          .readings-grid(v-if="(currentItem.onyomi && currentItem.onyomi.length > 0) || (currentItem.kunyomi && currentItem.kunyomi.length > 0)")
            .reading-box.reading-box--small(v-if="currentItem.onyomi && currentItem.onyomi.length > 0")
              .label
                ScrambleText(:text="$t('collection.onyomi')")
              .val.text-cyan-lighten-3 {{ currentItem.onyomi.join(', ') }}
            .reading-box.reading-box--small(v-if="currentItem.kunyomi && currentItem.kunyomi.length > 0")
              .label
                ScrambleText(:text="$t('collection.kunyomi')")
              .val.text-pink-lighten-3 {{ currentItem.kunyomi.join(', ') }}

        .review-canvas-area
          KanjiCanvas(
            :key="canvasKey"
            ref="kanjiCanvasRef"
            :char="currentItem.char"
            @complete="handleComplete"
            @mistake="handleMistake"
          )

          transition(name="scale")
            v-btn.next-fab.glow-btn.text-black(
              v-if="showNext"
              @click="next"
              color="primary"
              icon="mdi-arrow-right"
              size="large"
              elevation="8"
            )

        .mb-4.d-flex.gap-2
          v-btn.text-caption.font-weight-bold.opacity-80(
            variant="text"
            color="amber-lighten-1"
            prepend-icon="mdi-lightbulb-outline"
            size="small"
            :disabled="showNext"
            @click="triggerHint"
          )
            ScrambleText(:text="$t('review.showHint')")

        v-sheet.d-flex.flex-column.align-center.justify-center(
          width="100%"
          min-height="80"
          color="transparent"
        )
          transition(name="fade-slide" mode="out-in")
            .status-text.text-h6.font-weight-bold(
              :key="statusCode"
              :class="getStatusClass(statusCode)"
            )
              ScrambleText(:text="$t('review.' + statusCode)")

          transition(name="scale")
            v-chip.mt-2.font-weight-bold.elevation-2(
              v-if="showNext && rankChange"
              :color="rankChange.type === 'up' ? 'teal-accent-4' : 'red-darken-1'"
              variant="flat"
              size="small"
            )
              v-icon(start size="14") {{ rankChange.type === 'up' ? 'mdi-arrow-up-thick' : 'mdi-arrow-down-thick' }}
              | Level {{ currentItem.srsLevel }} &rarr; {{ rankChange.level }}

        v-progress-linear.mt-4.progress-bar(
          v-model="progressPercent"
          color="primary"
          height="4"
          rounded
        )

      v-card.pa-8.rounded-xl.elevation-10.review-card(
        v-else-if="sessionTotal > 0 && store.queue.length === 0"
      )
        .d-flex.flex-column.align-center.mb-6
          v-avatar(color="rgba(0, 206, 201, 0.1)" size="80")
            v-icon(size="40" color="primary") mdi-trophy

          .text-h4.font-weight-bold.mt-4.mb-2
            ScrambleText(:text="$t('review.sessionComplete')")

        v-row.mb-4
          v-col.text-center.border-r.border-subtle(cols="6")
            .text-h3.font-weight-bold.text-white {{ accuracy }}%
            .text-caption.text-grey.text-uppercase.mt-1
              ScrambleText(:text="$t('stats.accuracy')")
          v-col.text-center(cols="6")
            .text-h3.font-weight-bold.text-white {{ sessionCorrect }}
            .text-caption.text-grey.text-uppercase.mt-1
              ScrambleText(:text="$t('stats.correct')")

        .d-flex.justify-center.ga-4.mb-6(v-if="levelUpCount > 0 || levelDownCount > 0")
          v-chip.font-weight-bold(
            v-if="levelUpCount > 0"
            color="teal-accent-4"
            variant="tonal"
            size="small"
            prepend-icon="mdi-arrow-up-thick"
          )
            ScrambleText(:text="$t('review.levelsUp', { n: levelUpCount })")
          v-chip.font-weight-bold(
            v-if="levelDownCount > 0"
            color="red-darken-1"
            variant="tonal"
            size="small"
            prepend-icon="mdi-arrow-down-thick"
          )
            ScrambleText(:text="$t('review.levelsDown', { n: levelDownCount })")

        .text-caption.text-grey.text-uppercase.tracking-wide.mb-3.text-left.w-100
          ScrambleText(:text="$t('review.results')")

        .result-list.w-100.mb-6
          .result-item(
            v-for="(r, i) in sessionResults"
            :key="i"
          )
            .result-char {{ r.char }}
            .result-meaning.text-grey {{ r.meaning }}
            v-spacer
            v-chip.font-weight-bold.mr-2(
              :color="r.success ? 'teal-accent-4' : 'red-darken-1'"
              variant="tonal"
              size="x-small"
            )
              v-icon(start size="12") {{ r.success ? 'mdi-check' : 'mdi-close' }}
              | {{ r.oldLevel }} &rarr; {{ r.newLevel }}

        v-btn.text-black.font-weight-bold.glow-btn(
          to="/"
          block
          color="primary"
          height="50"
          rounded="lg"
        )
          ScrambleText(:text="$t('review.back')")

      .text-center(v-else)
        v-icon.mb-4(size="64" color="grey-darken-2") mdi-check-circle-outline
        .text-h4.mb-2.text-white
          ScrambleText(:text="$t('review.caughtUp')")
        .text-grey.mb-6
          ScrambleText(:text="$t('review.noReviews')")
        v-btn.font-weight-bold(
          to="/"
          color="primary"
          variant="tonal"
        )
          ScrambleText(:text="$t('review.viewCollection')")
</template>

<script setup>
/* eslint-disable no-unused-vars */
import {
  ref, onMounted, computed, watch,
} from 'vue';
import { useRoute } from 'vue-router';
import { useAppStore } from '@/stores/appStore';
import KanjiCanvas from '@/components/kanji/KanjiCanvas.vue';
import { SoundManager } from '@/utils/SoundManager';

const store = useAppStore();
const route = useRoute();

const currentItem = ref(null);
const statusCode = ref('draw');
const showNext = ref(false);
const isFailure = ref(false);
const kanjiCanvasRef = ref(null);
const loading = ref(true);

const sessionTotal = ref(0);
const sessionDone = ref(0);
const sessionCorrect = ref(0);
const sessionResults = ref([]);

const accuracy = computed(() => {
  if (sessionDone.value === 0) return 100;
  return Math.round((sessionCorrect.value / sessionDone.value) * 100);
});

const progressPercent = computed(() => {
  if (sessionTotal.value === 0) return 0;
  return (sessionDone.value / sessionTotal.value) * 100;
});

const levelUpCount = computed(() => sessionResults.value.filter((r) => r.success).length);
const levelDownCount = computed(() => sessionResults.value.filter((r) => !r.success).length);

const submittedItems = ref(new Set());
const canvasKey = ref(0);

function loadNext() {
  if (store.queue.length === 0) {
    currentItem.value = null;
    if (sessionTotal.value > 0) SoundManager.playSessionComplete();
    return;
  }

  let idx = Math.floor(Math.random() * store.queue.length);

  if (store.queue.length > 1
    && currentItem.value
    && store.queue[idx]._id === currentItem.value._id
  ) idx = (idx + 1) % store.queue.length;

  currentItem.value = store.queue[idx];

  statusCode.value = 'draw';
  showNext.value = false;
  isFailure.value = false;
  canvasKey.value += 1;
}

const rankChange = computed(() => {
  if (!currentItem.value || !showNext.value) return null;

  if (submittedItems.value.has(currentItem.value._id)) return null;

  const current = currentItem.value.srsLevel;

  if (!isFailure.value) {
    if (current >= 10) return null;
    return { type: 'up', level: current + 1 };
  }
  if (current <= 1) return null;
  return { type: 'down', level: current - 1 };
});

onMounted(async () => {
  loading.value = true;
  const mode = route.query.mode || 'shuffled';
  await store.fetchQueue(mode);

  if (sessionTotal.value === 0 && store.queue.length > 0) {
    sessionTotal.value = store.queue.length;
  }
  loadNext();
  loading.value = false;
});

async function resetSession() {
  loading.value = true;
  sessionDone.value = 0;
  sessionCorrect.value = 0;
  sessionTotal.value = 0;
  sessionResults.value = [];
  submittedItems.value.clear();
  currentItem.value = null;
  const mode = route.query.mode || 'shuffled';
  await store.fetchQueue(mode);
  if (store.queue.length > 0) sessionTotal.value = store.queue.length;
  loadNext();
  loading.value = false;
}

watch(() => store.batchSize, async () => {
  resetSession();
});

function triggerHint() {
  if (!kanjiCanvasRef.value) return;

  isFailure.value = true;
  statusCode.value = 'hint';

  kanjiCanvasRef.value.drawGuide(true);
}

function handleMistake(isHint) {
  if (isHint) {
    isFailure.value = true;
    statusCode.value = 'hint';
  } else {
    statusCode.value = 'tryAgain';
  }
}

function handleComplete() {
  statusCode.value = 'correct';
  showNext.value = true;
}

async function next() {
  if (!currentItem.value) return;

  const itemId = currentItem.value._id;
  const isFirstAttempt = !submittedItems.value.has(itemId);

  if (isFirstAttempt) {
    const oldLevel = currentItem.value.srsLevel;
    const result = await store.submitReview(currentItem.value.wkSubjectId, !isFailure.value);
    submittedItems.value.add(itemId);

    const newLevel = result?.srsLevel ?? oldLevel;
    sessionResults.value.push({
      char: currentItem.value.char,
      meaning: currentItem.value.meaning,
      success: !isFailure.value,
      oldLevel,
      newLevel,
    });

    if (!isFailure.value) {
      sessionCorrect.value += 1;
    }
  }

  if (!isFailure.value) {
    sessionDone.value += 1;
    const index = store.queue.findIndex((i) => i._id === itemId);
    if (index !== -1) {
      store.queue.splice(index, 1);
    }
  }

  loadNext();
}
const getSRSColor = (lvl) => {
  const colors = {
    1: '#ff7675', 2: '#fdcb6e', 3: '#55efc4', 4: '#0984e3', 5: '#a29bfe', 6: '#6c5ce7',
    7: '#00cec9', 8: '#fd79a8', 9: '#e84393', 10: '#ffd700',
  };
  return colors[lvl] || 'grey';
};

const getStatusClass = (status) => {
  switch (status) {
    case 'hint': return 'text-red-lighten-1';
    case 'correct': return 'text-teal-accent-3';
    default: return 'text-grey-lighten-1';
  }
};
</script>

<style lang="scss" scoped>
@use '@/styles/abstracts' as *;

.review-view-container {
  min-height: 100%;
}

.result-list {
  max-height: 16rem;
  overflow-y: auto;
  @include scrollbar;
  border-radius: $radius-md;
  background: $bg-glass-subtle;
}

.result-item {
  display: flex;
  align-items: center;
  padding: $spacing-sm $spacing-md;
  border-bottom: $border-width-sm solid $color-border;

  &:last-child {
    border-bottom: none;
  }
}

.result-char {
  font-size: $font-lg;
  font-weight: $weight-bold;
  min-width: 2.5rem;
  text-align: center;
}

.result-meaning {
  font-size: $font-sm;
  margin-left: $spacing-sm;
}
</style>
