<template>
  <div class="detailed-report">
    <div class="report-header">
      <h3 class="report-title">详细报告</h3>
      <button class="toggle-all-btn" @click="toggleAll">
        {{ allExpanded ? '收起全部' : '展开全部' }}
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" :class="{ 'chevron-up': allExpanded }">
          <polyline points="6 9 12 15 18 9" />
        </svg>
      </button>
    </div>

    <!-- 按轮次分组 -->
    <div
      v-for="(roundData, roundIndex) in groupedByRound"
      :key="roundIndex"
      class="round-group"
    >
      <div class="round-label">Round {{ roundIndex + 1 }}</div>
      <div class="round-cards">
        <div
          v-for="sentence in roundData"
          :key="sentence.id"
          class="sentence-card"
          :class="{ 'card-student': sentence.role === 'student', 'card-expanded': expandedIds.has(sentence.id) }"
          @click="sentence.role === 'student' && hasDetails(sentence) && toggleExpand(sentence.id)"
        >
          <!-- 卡片主体 -->
          <div class="card-body" :class="{ 'body-student': sentence.role === 'student' }">
            <div class="card-left">
              <!-- 语音条（仅学生卡片，AI 无 audio_url 故纯文字呈现） -->
              <div v-if="sentence.role === 'student'" class="card-voice-bar bar-student">
                <button
                  class="card-play-btn play-student"
                  :disabled="!sentence.audioUrl"
                  @click.stop="handleSentencePlay(sentence)"
                >
                  <!-- loading -->
                  <svg
                    v-if="player.loadingId.value === sentence.id"
                    class="play-spinner"
                    width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                    stroke-width="2" stroke-linecap="round"
                  >
                    <path d="M21 12a9 9 0 1 1-6.219-8.56" />
                  </svg>
                  <!-- playing -->
                  <svg
                    v-else-if="player.playingId.value === sentence.id"
                    width="10" height="10" viewBox="0 0 24 24" fill="currentColor"
                  >
                    <rect x="6" y="4" width="4" height="16" /><rect x="14" y="4" width="4" height="16" />
                  </svg>
                  <!-- error -->
                  <svg
                    v-else-if="player.errorId.value === sentence.id"
                    width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                    stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                  >
                    <path d="M12 9v4" /><path d="M12 17h.01" />
                    <path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
                  </svg>
                  <!-- idle -->
                  <svg
                    v-else
                    width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                    stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
                  >
                    <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5" />
                    <path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
                  </svg>
                </button>
                <div class="card-waveform">
                  <div
                    v-for="i in 8"
                    :key="i"
                    class="card-wave-bar cw-student"
                    :style="{ height: `${Math.sin(i * 0.6) * 4 + 3}px` }"
                  />
                </div>
                <span class="card-duration cd-student">
                  {{ formatDuration(sentence.audioDuration) }}
                </span>
              </div>

              <!-- 文本 -->
              <p class="card-text">{{ sentence.content }}</p>
              <p v-if="sentence.contentZh" class="card-text-zh">{{ sentence.contentZh }}</p>
            </div>

            <!-- 评分标签 -->
            <div v-if="sentence.role === 'student' && hasDetails(sentence)" class="card-right">
              <span v-if="sentence.score !== undefined" class="card-score" :class="getScoreClass(sentence.score)">{{ sentence.score }}</span>
              <svg class="expand-icon" :class="{ 'expanded': expandedIds.has(sentence.id) }" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <polyline points="6 9 12 15 18 9" />
              </svg>
            </div>
          </div>

          <!-- 展开详情 -->
          <div v-if="sentence.role === 'student' && expandedIds.has(sentence.id)" class="card-detail">
            <!-- 发音评分 -->
            <div v-if="sentence.pronunciation" class="pron-scores">
              <div class="pron-row">
                <span class="pron-label">准确度</span>
                <div class="pron-track"><div class="pron-fill" :style="{ width: `${sentence.pronunciation.accuracy}%` }" /></div>
                <span class="pron-value">{{ sentence.pronunciation.accuracy }}</span>
              </div>
              <div class="pron-row">
                <span class="pron-label">语调</span>
                <div class="pron-track"><div class="pron-fill" :style="{ width: `${sentence.pronunciation.intonation}%` }" /></div>
                <span class="pron-value">{{ sentence.pronunciation.intonation }}</span>
              </div>
              <div class="pron-row">
                <span class="pron-label">重音</span>
                <div class="pron-track"><div class="pron-fill" :style="{ width: `${sentence.pronunciation.stress}%` }" /></div>
                <span class="pron-value">{{ sentence.pronunciation.stress }}</span>
              </div>
              <div class="pron-row">
                <span class="pron-label">流畅度</span>
                <div class="pron-track"><div class="pron-fill" :style="{ width: `${sentence.pronunciation.fluency}%` }" /></div>
                <span class="pron-value">{{ sentence.pronunciation.fluency }}</span>
              </div>
            </div>

            <!-- 反馈信息 -->
            <div v-if="sentence.feedback" class="feedback-section">
              <div v-if="sentence.feedback.comment" class="feedback-block">
                <div class="feedback-block-label"><span class="fb-good">✓</span> 一句话点评</div>
                <p class="feedback-text">{{ sentence.feedback.comment }}</p>
              </div>
              <div v-if="sentence.feedback.betterExpression" class="feedback-block">
                <div class="feedback-block-label"><span class="fb-suggest">→</span> 进阶表达</div>
                <p class="better-expression">{{ sentence.feedback.betterExpression }}</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import type { SentenceEvaluation } from '@/types/englishSpeaking'
import { useAudioPlayer } from '../composables/useAudioPlayer'

interface Props {
  sentenceEvaluations: SentenceEvaluation[]
}

const props = defineProps<Props>()

const player = useAudioPlayer()

const expandedIds = ref(new Set<string>())
const allExpanded = ref(false)

const groupedByRound = computed(() => {
  const groups: SentenceEvaluation[][] = []
  for (const s of props.sentenceEvaluations) {
    const idx = s.round - 1
    if (!groups[idx]) groups[idx] = []
    groups[idx].push(s)
  }
  return groups
})

function toggleExpand(id: string) {
  if (expandedIds.value.has(id)) {
    expandedIds.value.delete(id)
  } else {
    expandedIds.value.add(id)
  }
}

function toggleAll() {
  if (allExpanded.value) {
    expandedIds.value.clear()
  } else {
    props.sentenceEvaluations
      .filter(s => s.role === 'student' && hasDetails(s))
      .forEach(s => expandedIds.value.add(s.id))
  }
  allExpanded.value = !allExpanded.value
}

function hasDetails(sentence: SentenceEvaluation) {
  return Boolean(sentence.pronunciation || sentence.feedback)
}

function formatDuration(seconds: number | null | undefined): string {
  if (seconds == null || !Number.isFinite(seconds)) return '--:--'
  const total = Math.round(seconds)
  const mins = Math.floor(total / 60)
  const secs = total % 60
  return `${mins}:${String(secs).padStart(2, '0')}`
}

function handleSentencePlay(s: SentenceEvaluation) {
  if (!s.audioUrl) return
  // 同 id 二次点击：toggle 停止；否则播放新源
  if (player.playingId.value === s.id || player.loadingId.value === s.id) {
    player.stop()
    return
  }
  player.play(s.id, { kind: 'url', url: s.audioUrl })
}

function getScoreClass(score: number) {
  if (score >= 90) return 'score-excellent'
  if (score >= 80) return 'score-good'
  if (score >= 70) return 'score-fair'
  return 'score-low'
}
</script>

<style lang="scss" scoped>
.detailed-report {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.report-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.report-title { font-size: 14px; font-weight: 600; color: #111827; margin: 0; }
.toggle-all-btn {
  font-size: 11px;
  color: #f97316;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 2px;
  &:hover { color: #ea580c; }
  svg { transition: transform 0.2s; }
  .chevron-up { transform: rotate(180deg); }
}

.round-group { display: flex; flex-direction: column; gap: 6px; }
.round-label { font-size: 10px; font-weight: 500; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.5px; }

.round-cards { display: flex; flex-direction: column; gap: 6px; }

.sentence-card {
  background: #fff;
  border-radius: 10px;
  border: 1px solid #f3f4f6;
  overflow: hidden;
  transition: border-color 0.2s;
}
.card-student { cursor: pointer; &:hover { border-color: #fed7aa; } }
.card-expanded { border-color: rgba(249,115,22,0.3); }

.card-body {
  padding: 10px 12px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
.card-left { flex: 1; min-width: 0; }

// 卡片语音条
.card-voice-bar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 8px;
  margin-bottom: 4px;
}
.bar-ai { background: #fff; border: 1px solid #f3f4f6; }
.bar-student { background: #f97316; }

.card-play-btn {
  padding: 2px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
}
.play-ai { background: rgba(249,115,22,0.1); color: #f97316; }
.play-student { background: rgba(255,255,255,0.2); color: #fff; }

.card-waveform { display: flex; align-items: center; gap: 1px; }
.card-wave-bar { width: 1.5px; border-radius: 999px; }
.cw-ai { background: rgba(249,115,22,0.4); }
.cw-student { background: rgba(255,255,255,0.5); }

.card-duration { font-size: 9px; }
.cd-ai { color: #9ca3af; }
.cd-student { color: rgba(255,255,255,0.8); }

.card-text { font-size: 12px; color: #1f2937; margin: 0; line-height: 1.5; }
.card-text-zh { font-size: 10px; color: #9ca3af; margin: 2px 0 0; }

.card-right {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.card-score {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
}
.score-excellent { background: #dcfce7; color: #16a34a; }
.score-good { background: #dbeafe; color: #2563eb; }
.score-fair { background: #fef3c7; color: #d97706; }
.score-low { background: #fee2e2; color: #ef4444; }

.expand-icon {
  transition: transform 0.2s;
  &.expanded { transform: rotate(180deg); }
}

// 展开详情
.card-detail {
  padding: 10px 12px;
  border-top: 1px solid #f9fafb;
  background: #fafbfc;
}

.pron-scores { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.pron-row { display: flex; align-items: center; gap: 8px; }
.pron-label { font-size: 10px; color: #6b7280; width: 36px; flex-shrink: 0; }
.pron-track { flex: 1; height: 4px; background: #e5e7eb; border-radius: 999px; overflow: hidden; }
.pron-fill { height: 100%; background: #f97316; border-radius: 999px; transition: width 0.5s; }
.pron-value { font-size: 10px; font-weight: 500; color: #f97316; width: 20px; text-align: right; }

.feedback-section { display: flex; flex-direction: column; gap: 10px; }
.feedback-block { margin-bottom: 2px; }
.feedback-block-label { font-size: 10px; color: #6b7280; display: flex; align-items: center; gap: 4px; margin-bottom: 4px; }
.fb-good { color: #22c55e; }
.fb-fix { color: #3b82f6; }
.fb-suggest { color: #f59e0b; }
.feedback-text {
  margin: 0;
  font-size: 11px;
  color: #4b5563;
  line-height: 1.5;
}
.better-expression {
  margin: 0;
  padding: 8px 10px;
  background: #fff;
  border: 1px solid #f3f4f6;
  border-radius: 8px;
  font-size: 12px;
  color: #111827;
  line-height: 1.5;
}
.feedback-list {
  margin: 0;
  padding-left: 16px;
  li { font-size: 10px; color: #4b5563; line-height: 1.6; }
}

.correction-item { margin-bottom: 6px; }
.correction-row { display: flex; align-items: center; gap: 4px; font-size: 11px; }
.correction-original { color: #ef4444; text-decoration: line-through; }
.correction-arrow { color: #9ca3af; }
.correction-corrected { color: #22c55e; font-weight: 500; }
.correction-explanation { font-size: 10px; color: #6b7280; margin: 2px 0 0; }
</style>
