<template>
  <div class="article-class-panel" :style="cardStyle">
    <div class="content-card">
      <div v-if="!props.configId" class="state-banner">
        {{ lang.ssSpkConfigMissing }}
      </div>

      <template v-else>
        <!-- 状态筛选 + 排序 -->
        <div class="filter-row">
          <div class="status-filter">
            <button
              v-for="tab in filterTabs"
              :key="tab.key"
              :class="{ active: statusFilter === tab.key }"
              @click="statusFilter = tab.key"
            >
              {{ tab.label }} {{ tab.count }}
            </button>
          </div>
          <SortMenu v-model="sortBy" />
        </div>

        <div v-if="error === 'FETCH_FAILED'" class="error-bar">
          <span>{{ lang.ssSpkLoadFailed }}</span>
          <button @click="fetchClassSummary">{{ lang.ssSpkRetry }}</button>
        </div>

        <div class="grid-scroll">
          <StudentGrid :students="filteredAndSortedStudents" @click="handleStudentClick" />
        </div>

        <ClassSummary
          :summary="aiSummary"
          :loading="aiLoading"
          :error="aiError"
          :generated-at="aiGeneratedAt"
          @refresh="refreshAISummary"
        />
      </template>
    </div>

    <StudentReportModal
      v-if="reportModalStudent && reportModalStudent.sessionId"
      :student="reportModalStudent"
      @close="reportModalStudent = null"
    />

    <NotStartedTip
      v-if="notStartedTipStudent"
      :studentName="notStartedTipStudent.name"
      @close="notStartedTipStudent = null"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, toRef } from 'vue'
import { lang } from '@/main'
import SortMenu, { type SortKey } from '../SpeakingClassPanel/SortMenu.vue'
import NotStartedTip from '../SpeakingClassPanel/NotStartedTip.vue'
import StudentGrid from './StudentGrid.vue'
import ClassSummary from './ClassSummary.vue'
import StudentReportModal from './StudentReportModal.vue'
import { useArticleClassSummary } from './useArticleClassSummary'
import type { ArticleClassStudent, ArticleClassFilter } from './types'
import type { ArticleClassSessionSummary } from '@/types/articleReading'

const props = defineProps<{
  configId: string
  slideIndex: number
  studentArray: ArticleClassStudent[]
  courseId: string
  slideWidth: number
  slideHeight: number
}>()

const {
  summaries, error, fetchClassSummary, scheduleRefetch,
  aiSummary, aiLoading, aiError, aiGeneratedAt, refreshAISummary,
} = useArticleClassSummary({
  configId: toRef(props, 'configId'),
  studentArray: toRef(props, 'studentArray'),
})

// 父级 Student/index.vue 通过 ref 调用
defineExpose({ scheduleRefetch, fetchClassSummary })

const statusFilter = ref<ArticleClassFilter>('all')
const sortBy = ref<SortKey>('time-asc')

// 状态沿用后端原生 completed / reading / not_started，不翻译成对话的提交模型
const counts = computed(() => ({
  all: summaries.value.length,
  completed: summaries.value.filter(s => s.status === 'completed').length,
  reading: summaries.value.filter(s => s.status === 'reading').length,
  not_started: summaries.value.filter(s => s.status === 'not_started').length,
}))

const filterTabs = computed(() => [
  { key: 'all' as ArticleClassFilter, label: lang.ssSpkFilterAll as string, count: counts.value.all },
  { key: 'completed' as ArticleClassFilter, label: lang.ssArticleFilterCompleted as string, count: counts.value.completed },
  { key: 'reading' as ArticleClassFilter, label: lang.ssArticleFilterReading as string, count: counts.value.reading },
  { key: 'not_started' as ArticleClassFilter, label: lang.ssSpkFilterNotStarted as string, count: counts.value.not_started },
])

const filteredAndSortedStudents = computed(() => {
  let arr = summaries.value
  if (statusFilter.value !== 'all') arr = arr.filter(s => s.status === statusFilter.value)
  arr = [...arr]
  if (sortBy.value === 'name-asc') {
    arr.sort((a, b) => a.name.localeCompare(b.name, 'zh-CN'))
  } else {
    arr.sort((a, b) => {
      const ta = a.completedAt || ''
      const tb = b.completedAt || ''
      return sortBy.value === 'time-desc' ? tb.localeCompare(ta) : ta.localeCompare(tb)
    })
  }
  return arr
})

const reportModalStudent = ref<ArticleClassSessionSummary | null>(null)
const notStartedTipStudent = ref<ArticleClassSessionSummary | null>(null)

function handleStudentClick(student: ArticleClassSessionSummary) {
  if (student.status === 'not_started' || !student.sessionId) {
    notStartedTipStudent.value = student
  } else {
    reportModalStudent.value = student
  }
}

const cardStyle = computed(() => ({
  width: props.slideWidth + 'px',
  height: props.slideHeight + 'px',
}))
</script>

<style lang="scss" scoped>
.article-class-panel {
  margin: 0 auto;
  background: #f9fafb;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
}

.content-card {
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  width: 100%;
  max-width: 900px;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 32px 48px;
  overflow: hidden;
}

.state-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  color: #9ca3af;
  font-size: 14px;
}

.filter-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  margin-bottom: 12px;
}

.status-filter {
  display: flex;
  gap: 8px;

  button {
    padding: 4px 12px;
    border: 1px solid #e5e7eb;
    border-radius: 999px;
    background: #fff;
    color: #6b7280;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.2s;

    &:hover { background: #f9fafb; }

    &.active {
      background: #f97316;
      border-color: #f97316;
      color: #fff;
    }
  }
}

.error-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  margin-bottom: 8px;
  padding: 8px 12px;
  border-radius: 8px;
  background: #fef2f2;
  color: #dc2626;
  font-size: 12px;

  button {
    padding: 2px 10px;
    border: 1px solid #fecaca;
    border-radius: 999px;
    background: #fff;
    color: #dc2626;
    font-size: 11px;
    cursor: pointer;
  }
}

.grid-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
</style>
