<template>
  <div class="speaking-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="f in filterTabs"
              :key="f.key"
              :class="{ 'active': statusFilter === f.key }"
              @click="statusFilter = f.key"
            >
              {{ f.label }} {{ f.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>

        <!-- AI 总结 -->
        <AISummary
          :bullets="aiBullets"
          :loading="aiLoading"
          :generatedAt="aiGeneratedAt"
          @refresh="refreshAISummary"
        />
      </template>
    </div>

    <StudentReportModal
      v-if="reportModalStudent && reportModalStudent.sessionId"
      :student="reportModalStudent"
      :role="defaultRole"
      @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 StudentGrid from './StudentGrid.vue'
import SortMenu, { type SortKey } from './SortMenu.vue'
import AISummary from './AISummary.vue'
import StudentReportModal from './StudentReportModal.vue'
import NotStartedTip from './NotStartedTip.vue'
import { useClassSummary } from './useClassSummary'
import type { ClassStudent, ClassStudentSummary, ClassStudentStatus, Locale } from './types'
import type { PreviewAIRole } from '@/types/englishSpeaking'

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

// locale 派生:简单按 hostname 决定(与 src/i18n/lang.ts 镜像)
const locale = ref<Locale>(
  /cocorobo\.com/i.test(window.location.href) ? 'en'
  : /cocorobo\.hk/i.test(window.location.href) ? 'hk'
  : 'zh'
)

const {
  summaries, loading, error, fetchClassSummary, scheduleRefetch,
  aiBullets, aiLoading, aiGeneratedAt, refreshAISummary,
} = useClassSummary({
  configId: toRef(props, 'configId'),
  studentArray: toRef(props, 'studentArray'),
  locale,
})

// 暴露给父级(Student/index.vue)用 ref 调用
defineExpose({ scheduleRefetch, fetchClassSummary })

// 状态筛选 / 排序
type Filter = 'all' | ClassStudentStatus
const statusFilter = ref<Filter>('all')
const sortBy = ref<SortKey>('time-asc')

const counts = computed(() => ({
  all: summaries.value.length,
  submitted: summaries.value.filter(s => s.status === 'submitted').length,
  unsubmitted: summaries.value.filter(s => s.status === 'unsubmitted').length,
  not_started: summaries.value.filter(s => s.status === 'not_started').length,
}))

const filterTabs = computed(() => [
  { key: 'all'         as Filter, label: (lang as any).ssSpkFilterAll,         count: counts.value.all },
  { key: 'submitted'   as Filter, label: (lang as any).ssSpkFilterSubmitted,   count: counts.value.submitted },
  { key: 'unsubmitted' as Filter, label: (lang as any).ssSpkFilterUnsubmitted, count: counts.value.unsubmitted },
  { key: 'not_started' as Filter, label: (lang as any).ssSpkFilterNotStarted,  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 || a.createdAt || ''
      const tb = b.completedAt || b.createdAt || ''
      return sortBy.value === 'time-desc' ? tb.localeCompare(ta) : ta.localeCompare(tb)
    })
  }
  return arr
})

// 点击学生
const reportModalStudent = ref<ClassStudentSummary | null>(null)
const notStartedTipStudent = ref<ClassStudentSummary | null>(null)

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

// 占位 role(MVP):后续可从 config 拉
const defaultRole: PreviewAIRole = {
  id: 'amy', name: 'Amy', avatar: '😊',
  identity: 'Friendly Teacher',
  personality: 'Patient and encouraging',
  speakingStyle: 'casual', speed: 'normal',
  isCustom: false, isRecommended: true,
}

// 卡片整体尺寸样式
const cardStyle = computed(() => ({
  width: props.slideWidth + 'px',
  height: props.slideHeight + 'px',
}))
</script>

<style lang="scss" scoped>
.speaking-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,.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;
  margin-bottom: 16px;
}
.status-filter {
  display: flex; gap: 4px;

  button {
    padding: 4px 10px;
    border-radius: 6px;
    background: transparent;
    border: none;
    font-size: 12px;
    font-weight: 500;
    color: #6b7280;
    cursor: pointer;
    transition: background .15s;
    &:hover:not(.active) { background: #f3f4f6; }
    &.active {
      background: #facc15;
      color: #111827;
    }
  }
}

.error-bar {
  background: #fef2f2;
  color: #b91c1c;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;

  button {
    padding: 2px 8px;
    background: #fff;
    border: 1px solid #fecaca;
    border-radius: 4px;
    cursor: pointer;
    color: #b91c1c;
    font-size: 12px;
    &:hover { background: #fee2e2; }
  }
}

.grid-scroll {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 16px;
}
</style>
