<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import GlassCard from '@/components/ui/GlassCard.vue'
import DataTable from '@/components/ui/DataTable.vue'
import StatusBadge from '@/components/ui/StatusBadge.vue'
import EmptyState from '@/components/ui/EmptyState.vue'
import { reviewsApi } from '@/api'
import type { ReviewDto } from '@/api/types'

const columns = [
  { key: 'id', label: 'ID' },
  { key: 'lecture', label: 'Лекция' },
  { key: 'student', label: 'Студент' },
  { key: 'rating', label: 'Оценка', align: 'center' },
  { key: 'text', label: 'Текст' },
  { key: 'date', label: 'Дата' },
  { key: 'status', label: 'LLM-статус', align: 'center' },
  { key: 'sentiment', label: 'Sentiment', align: 'center' },
  { key: 'quality', label: 'Quality', align: 'center' },
  { key: 'informativeTags', label: 'Informative / tags' },
  { key: 'actions', label: 'Действия', align: 'right' },
]

const statusMap: Record<string, string> = {
  Pending: 'pending',
  Analyzed: 'done',
  Rejected: 'rejected',
}

const ratingLabel: Record<string, string> = {
  Like: '👍 Like',
  Neutral: '😐 Neutral',
  Dislike: '👎 Dislike',
}

const reviews = ref<ReviewDto[]>([])
const loading = ref(false)
const page = ref(1)
const pageSize = ref(20)
const totalCount = ref(0)
const totalPages = ref(0)
const reanalyzingId = ref<number | null>(null)
const error = ref('')

const rows = computed(() =>
  reviews.value.map((review) => ({
    id: review.id,
    lecture: review.lectureTitle || `#${review.lectureId}`,
    student: review.userName || `#${review.userId}`,
    rating: ratingLabel[review.rating] ?? review.rating,
    text: review.text || '—',
    date: new Date(review.createdAt).toLocaleString('ru-RU'),
    status: statusMap[review.llmStatus] ?? review.llmStatus,
    rawStatus: review.llmStatus,
    sentiment: review.sentiment,
    quality: review.qualityScore,
    informative: review.isInformative,
    tags: review.llmTags ?? [],
    informativeTags: [
      review.isInformative === null || review.isInformative === undefined
        ? '—'
        : review.isInformative
          ? 'Да'
          : 'Нет',
      ...(review.llmTags ?? []),
    ].join(' / '),
  })),
)

const pageStart = computed(() =>
  totalCount.value === 0 ? 0 : (page.value - 1) * pageSize.value + 1,
)
const pageEnd = computed(() => Math.min(page.value * pageSize.value, totalCount.value))
const canGoPrev = computed(() => page.value > 1)
const canGoNext = computed(() => page.value < totalPages.value)

function formatQuality(value: number | null | undefined) {
  if (value === null || value === undefined) return '—'
  return Number(value).toFixed(2)
}

async function fetchReviews() {
  loading.value = true
  error.value = ''
  try {
    const result = await reviewsApi.listPage({
      Page: page.value,
      PageSize: pageSize.value,
    })
    reviews.value = result.items
    totalCount.value = result.totalCount
    totalPages.value = result.totalPages
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Не удалось загрузить отзывы.'
  } finally {
    loading.value = false
  }
}

async function goToPage(nextPage: number) {
  if (nextPage < 1 || (totalPages.value && nextPage > totalPages.value)) return
  page.value = nextPage
  await fetchReviews()
}

async function reanalyze(id: number) {
  reanalyzingId.value = id
  try {
    await reviewsApi.reanalyze(id)
    await fetchReviews()
  } catch (err) {
    error.value = err instanceof Error ? err.message : 'Не удалось запустить повторный анализ.'
  } finally {
    reanalyzingId.value = null
  }
}

onMounted(fetchReviews)
</script>

<template>
  <div class="admin-reviews page-content">
    <div class="header">
      <div>
        <h1 class="page-title">Отзывы</h1>
        <p class="page-subtitle">Все отзывы студентов и результаты LLM-анализа.</p>
      </div>
      <button class="btn-primary" :disabled="loading" @click="fetchReviews">
        {{ loading ? 'Загрузка...' : 'Обновить отзывы' }}
      </button>
    </div>

    <GlassCard>
      <EmptyState v-if="error" title="Не удалось загрузить отзывы" :subtitle="error" />
      <EmptyState
        v-else-if="!rows.length && !loading"
        title="Отзывов нет"
        subtitle="Пока нет ни одного отзыва."
      />
      <div v-else class="table-section">
        <div class="pagination-bar">
          <span> Показаны {{ pageStart }}–{{ pageEnd }} из {{ totalCount }} отзывов </span>
          <div class="pagination-actions">
            <button class="btn-ghost" :disabled="loading || !canGoPrev" @click="goToPage(page - 1)">
              Назад
            </button>
            <span>Страница {{ page }} из {{ totalPages || 1 }}</span>
            <button class="btn-ghost" :disabled="loading || !canGoNext" @click="goToPage(page + 1)">
              Вперёд
            </button>
          </div>
        </div>
        <DataTable :columns="columns" :rows="rows">
          <template #text="{ value }">
            <span class="review-text" :title="value">{{ value }}</span>
          </template>
          <template #status="{ value, row }">
            <StatusBadge :status="value" />
            <span class="raw-status">{{ row.rawStatus }}</span>
          </template>
          <template #sentiment="{ value }">
            <span
              class="badge"
              :class="
                value === 'Positive'
                  ? 'badge-green'
                  : value === 'Negative'
                    ? 'badge-red'
                    : 'badge-orange'
              "
            >
              {{ value }}
            </span>
          </template>
          <template #quality="{ value }">
            <span
              :class="
                (value ?? 0) >= 0.7
                  ? 'badge badge-green'
                  : (value ?? 0) >= 0.4
                    ? 'badge badge-orange'
                    : 'badge badge-red'
              "
            >
              {{ formatQuality(value) }}
            </span>
          </template>
          <template #informativeTags="{ row }">
            <div class="tags-cell">
              <span
                class="badge"
                :class="
                  row.informative
                    ? 'badge-green'
                    : row.informative === false
                      ? 'badge-red'
                      : 'badge-gray'
                "
              >
                {{
                  row.informative === null || row.informative === undefined
                    ? '—'
                    : row.informative
                      ? 'Informative'
                      : 'Not informative'
                }}
              </span>
              <span v-for="tag in row.tags" :key="tag" class="badge badge-blue">{{ tag }}</span>
            </div>
          </template>
          <template #actions="{ row }">
            <button
              class="btn-ghost"
              :disabled="reanalyzingId === row.id"
              @click="reanalyze(row.id)"
            >
              {{ reanalyzingId === row.id ? 'Запускаем...' : 'Повторить анализ' }}
            </button>
          </template>
        </DataTable>
      </div>
    </GlassCard>
  </div>
</template>

<style scoped>
.admin-reviews {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.page-subtitle {
  margin: 4px 0 0;
  color: var(--color-text-secondary);
}
.review-text {
  display: inline-block;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}
.raw-status {
  display: block;
  margin-top: 4px;
  color: var(--color-text-secondary);
  font-size: 11px;
}
.table-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pagination-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  color: var(--color-text-secondary);
  font-size: 13px;
}
.pagination-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tags-cell {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 160px;
}
</style>
