<script setup>
import { ref, computed, onUnmounted } from "vue";
import { useRouter } from "vue-router";
import axios from "axios";

import {
  GRS_API_KEY,
  QUESTION_API_URL,
  QUESTION_MODEL,
  QUESTION_TEMPERATURE,
  QUESTION_MAX_TOKENS,
  QUESTION_GENERATOR_PROMPT,
} from "@/config/index.js";

const router = useRouter();

const API_KEY = GRS_API_KEY;
const API_URL = QUESTION_API_URL;

// ── 状态 ──
const status = ref("idle"); // 'idle' | 'generating' | 'done' | 'error'
const errorMsg = ref("");
const rawContent = ref("");
const cancelTokenSource = ref(null);

// ── 参数配置 ──
const difficulty = ref("medium"); // 'easy' | 'medium' | 'hard'
const questionCount = ref(5);

// 新增维度：教材章节、知识点、题型
const textbookChapter = ref(""); // 教材章节（预设）
const customTextbookChapter = ref(""); // 自定义教材章节输入
const selectedKnowledgePoints = ref([]); // 选中的知识点
const customKnowledgePoint = ref(""); // 自定义知识点输入
const questionFormat = ref("单项选择"); // 题型（预设）
const customQuestionFormat = ref(""); // 自定义题型输入

// ── 配置选项 ──
const DIFFICULTY_OPTIONS = [
  { value: "very_easy", label: "容易", color: "#10b981" },
  { value: "easy", label: "较易", color: "#34d399" },
  { value: "medium", label: "适中", color: "#f59e0b" },
  { value: "hard", label: "较难", color: "#f97316" },
  { value: "very_hard", label: "困难", color: "#ef4444" },
];

// 教材章节预设选项
const CHAPTER_OPTIONS = [
  { value: "Starter Unit1 You and Me", label: "Starter Unit1 You and Me" },
  { value: "Starter Unit2 Keep Tidy", label: "Starter Unit2 Keep Tidy" },
  { value: "Starter Unit3 Welcome!", label: "Starter Unit3 Welcome!" },
  { value: "Unit 1 You and Me", label: "Unit 1 You and Me" },
  { value: "Unit 2 We're Family!", label: "Unit 2 We're Family!" },
  { value: "Unit 3 My School", label: "Unit 3 My School" },
];

// 知识点预设选项
const KNOWLEDGE_POINT_OPTIONS = [
  { value: "语法", label: "语法" },
  { value: "词汇", label: "词汇" },
  { value: "冠词", label: "冠词" },
  { value: "不定冠词", label: "不定冠词" },
  { value: "定冠词", label: "定冠词" },
  { value: "名词", label: "名词" },
  { value: "动词", label: "动词" },
  { value: "形容词", label: "形容词" },
  { value: "代词", label: "代词" },
  { value: "介词", label: "介词" },
  { value: "时态", label: "时态" },
  { value: "一般现在时", label: "一般现在时" },
  { value: "现在进行时", label: "现在进行时" },
  { value: "一般过去时", label: "一般过去时" },
  { value: "句型结构", label: "句型结构" },
  { value: "阅读理解", label: "阅读理解" },
  { value: "写作", label: "写作" },
];

// 题型预设选项
const FORMAT_OPTIONS = [
  { value: "单项选择", label: "单项选择" },
  { value: "完形填空", label: "完形填空" },
  { value: "句型转换", label: "句型转换" },
  { value: "词汇运用", label: "词汇运用" },
  { value: "翻译句子", label: "翻译句子" },
  { value: "阅读理解", label: "阅读理解" },
  { value: "书面表达", label: "书面表达" },
  { value: "短文填空", label: "短文填空" },
  { value: "语法填空", label: "语法填空" },
  { value: "选词填空", label: "选词填空" },
];

// 切换知识点选中状态
const toggleKnowledgePoint = (value) => {
  const index = selectedKnowledgePoints.value.indexOf(value);
  if (index > -1) {
    selectedKnowledgePoints.value.splice(index, 1);
  } else {
    selectedKnowledgePoints.value.push(value);
  }
};

// ── 解析试题内容 ──
const parsedQuestions = computed(() => {
  const raw = rawContent.value;
  if (!raw) return [];

  const questions = [];
  const questionBlocks = raw.split(/##\s*题目\s*\d+/i);

  questionBlocks.forEach((block, index) => {
    if (index === 0) return; // 跳过第一个空块

    const question = {
      id: index,
      type: extractField(block, "题目类型"),
      difficulty: extractField(block, "难度等级"),
      content: extractField(block, "题目内容"),
      options: extractOptions(block),
      answer: extractField(block, "正确答案"),
      explanation: extractField(block, "解析"),
      knowledgePoint: extractField(block, "知识点"),
    };

    if (question.content) {
      questions.push(question);
    }
  });

  return questions;
});

function extractField(text, fieldName) {
  const regex = new RegExp(`\\*\\*${fieldName}\\*\\*[：:]\\s*([\\s\\S]*?)(?=\\*\\*|$)`, "i");
  const match = text.match(regex);
  if (!match) return "";

  let content = match[1].trim();
  // 清理可能混入的下一个字段
  content = content.split(/\*\*/)[0].trim();
  return content;
}

function extractOptions(text) {
  const options = [];
  
  // 先尝试提取"选项"字段的内容块
  const optionsBlockMatch = text.match(/\*\*选项\*\*[：:]\s*([\s\S]*?)(?=\*\*正确答案\*\*|$)/i);
  
  if (optionsBlockMatch) {
    const optionsBlock = optionsBlockMatch[1];
    
    // 在选项块中提取各个选项
    const lines = optionsBlock.split('\n');
    for (const line of lines) {
      const match = line.match(/^([A-D])[\.．。:：]\s*(.+)$/i);
      if (match) {
        options.push({
          label: match[1].toUpperCase(),
          content: match[2].trim(),
        });
      }
    }
  }
  
  return options;
}

// ── 构建请求体 ──
const buildRequestBody = () => {
  const difficultyLabel =
    DIFFICULTY_OPTIONS.find((d) => d.value === difficulty.value)?.label || "中等";

  // 构建知识点字符串：预设选项 + 自定义输入
  const allKnowledgePoints = [
    ...selectedKnowledgePoints.value,
    ...(customKnowledgePoint.value ? [customKnowledgePoint.value] : []),
  ];
  const knowledgePointStr = allKnowledgePoints.length > 0 ? allKnowledgePoints.join("、") : "";

  // 教材章节：优先使用自定义输入，否则使用预设选择
  const chapterStr = customTextbookChapter.value || textbookChapter.value || "";

  // 题型：优先使用自定义输入，否则使用预设选择
  const formatStr = customQuestionFormat.value || questionFormat.value || "";

  const userPrompt = `请生成 ${questionCount.value} 道${difficultyLabel}难度的英语试题。

要求：
1. 题型：${formatStr}
2. 难度等级：${difficultyLabel}
3. 题目数量：${questionCount.value} 道
${chapterStr ? `4. 教材章节：${chapterStr}` : ""}
${knowledgePointStr ? `5. 知识点：${knowledgePointStr}` : ""}

请严格按照指定的输出格式生成试题。`;

  return {
    model: QUESTION_MODEL,
    messages: [
      { role: "system", content: QUESTION_GENERATOR_PROMPT },
      { role: "user", content: userPrompt },
    ],
    temperature: QUESTION_TEMPERATURE,
    max_tokens: QUESTION_MAX_TOKENS,
    stream: true,
  };
};

// ── 提取 SSE delta 文本 ──
const extractTextDelta = (chunk) => {
  let result = "";
  const lines = chunk.split("\n");
  for (const line of lines) {
    if (!line.startsWith("data: ")) continue;
    const jsonStr = line.slice(6).trim();
    if (!jsonStr || jsonStr === "[DONE]") continue;
    try {
      const data = JSON.parse(jsonStr);
      const text = data?.choices?.[0]?.delta?.content;
      if (text) result += text;
    } catch {
      // 忽略解析失败的行
    }
  }
  return result;
};

// ── 过滤 HexString思考块 ──
const filterThinkBlocks = (text) => {
  let filtered = text.replace(/HexString[\s\S]*?<\/think>/g, "");
  filtered = filtered.replace(/HexString[\s\S]*$/, "");
  return filtered;
};

// ── 开始生成 ──
const canGenerate = computed(() => {
  return status.value !== "generating" && questionCount.value >= 1 && questionCount.value <= 20;
});

const startGeneration = async () => {
  if (!canGenerate.value) return;

  status.value = "generating";
  errorMsg.value = "";
  rawContent.value = "";

  cancelTokenSource.value = axios.CancelToken.source();
  let lastLength = 0;

  await axios
    .post(API_URL, buildRequestBody(), {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${API_KEY}`,
      },
      responseType: "text",
      cancelToken: cancelTokenSource.value.token,
      onDownloadProgress: (event) => {
        const text = (event.target || event.event?.target)?.responseText || "";
        if (!text) return;
        const newChunk = text.slice(lastLength);
        lastLength = text.length;
        const delta = extractTextDelta(newChunk);
        if (delta) {
          rawContent.value = filterThinkBlocks(rawContent.value + delta);
        }
      },
    })
    .then(() => {
      status.value = "done";
    })
    .catch((err) => {
      if (axios.isCancel(err)) return;
      console.error(err);
      errorMsg.value =
        err?.response?.data?.error?.message || err.message || "请求失败，请稍后重试";
      status.value = "error";
    });
};

const resetAll = () => {
  status.value = "idle";
  rawContent.value = "";
  errorMsg.value = "";
};

const loadExample = () => {
  difficulty.value = "medium";
  questionCount.value = 3;
  textbookChapter.value = "Starter Unit2 Keep Tidy";
  customTextbookChapter.value = "";
  selectedKnowledgePoints.value = ["语法", "冠词", "不定冠词"];
  customKnowledgePoint.value = "";
  questionFormat.value = "句型转换";
  customQuestionFormat.value = "";
};

const goBack = () => router.back();

onUnmounted(() => {
  if (cancelTokenSource.value) {
    cancelTokenSource.value.cancel("组件卸载，取消请求");
  }
});
</script>

<template>
  <div class="page-container">
    <!-- Nav Bar -->
    <div class="nav-bar">
      <button class="back-btn" @click="goBack">
        <svg
          width="20"
          height="20"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2.2"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <polyline points="15 18 9 12 15 6" />
        </svg>
        <span>返回</span>
      </button>
      <h1 class="nav-title">AI 试题生成</h1>
      <div style="width: 72px"></div>
    </div>

    <!-- Error Banner -->
    <div v-if="errorMsg" class="error-banner">
      <span>{{ errorMsg }}</span>
      <button class="error-close" @click="errorMsg = ''">✕</button>
    </div>

    <!-- Main Layout: Left + Right -->
    <div class="main-layout">
      <!-- Left Panel: Config -->
      <div class="left-panel">
        <div class="config-card">
          <div class="config-header">
            <svg
              width="20"
              height="20"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <circle cx="12" cy="12" r="3" />
              <path
                d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
              />
            </svg>
            <span>参数配置</span>
          </div>

          <div class="config-body">
            <!-- 难度等级 -->
            <div class="config-item">
              <label class="config-label">难度等级</label>
              <div class="difficulty-group">
                <button
                  v-for="opt in DIFFICULTY_OPTIONS"
                  :key="opt.value"
                  class="difficulty-btn"
                  :class="{ active: difficulty === opt.value }"
                  :style="{ '--accent-color': opt.color }"
                  @click="difficulty = opt.value"
                  :disabled="status === 'generating'"
                >
                  {{ opt.label }}
                </button>
              </div>
            </div>

            <!-- 题目数量 -->
            <div class="config-item">
              <label class="config-label">
                题目数量
                <span class="count-value">{{ questionCount }} 道</span>
              </label>
              <input
                type="range"
                v-model.number="questionCount"
                min="1"
                max="20"
                class="range-slider"
                :disabled="status === 'generating'"
              />
              <div class="range-labels">
                <span>1</span>
                <span>10</span>
                <span>20</span>
              </div>
            </div>

            <!-- 教材章节 -->
            <div class="config-item">
              <label class="config-label">教材章节（可选）</label>
              <select
                v-model="textbookChapter"
                class="select-input"
                :disabled="status === 'generating'"
              >
                <option value="">请选择教材章节</option>
                <option
                  v-for="opt in CHAPTER_OPTIONS"
                  :key="opt.value"
                  :value="opt.value"
                >
                  {{ opt.label }}
                </option>
              </select>
              <input
                type="text"
                v-model="customTextbookChapter"
                class="topic-input mt-2"
                placeholder="或输入自定义教材章节..."
                :disabled="status === 'generating'"
              />
            </div>

            <!-- 知识点 -->
            <div class="config-item">
              <label class="config-label">知识点（可多选）</label>
              <div class="knowledge-grid">
                <button
                  v-for="opt in KNOWLEDGE_POINT_OPTIONS"
                  :key="opt.value"
                  class="knowledge-btn"
                  :class="{ active: selectedKnowledgePoints.includes(opt.value) }"
                  @click="toggleKnowledgePoint(opt.value)"
                  :disabled="status === 'generating'"
                >
                  {{ opt.label }}
                </button>
              </div>
              <input
                type="text"
                v-model="customKnowledgePoint"
                class="topic-input mt-2"
                placeholder="或输入自定义知识点..."
                :disabled="status === 'generating'"
              />
            </div>

            <!-- 题型 -->
            <div class="config-item">
              <label class="config-label">题型</label>
              <select
                v-model="questionFormat"
                class="select-input"
                :disabled="status === 'generating'"
              >
                <option
                  v-for="opt in FORMAT_OPTIONS"
                  :key="opt.value"
                  :value="opt.value"
                >
                  {{ opt.label }}
                </option>
              </select>
              <input
                type="text"
                v-model="customQuestionFormat"
                class="topic-input mt-2"
                placeholder="或输入自定义题型..."
                :disabled="status === 'generating'"
              />
            </div>

            <!-- 示例按钮 -->
            <button class="example-btn" @click="loadExample" :disabled="status === 'generating'">
              <svg
                width="16"
                height="16"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                <polyline points="14 2 14 8 20 8" />
                <line x1="16" y1="13" x2="8" y2="13" />
                <line x1="16" y1="17" x2="8" y2="17" />
              </svg>
              <span>加载示例</span>
            </button>
          </div>
        </div>

        <!-- Generate Button -->
        <div class="btn-wrap">
          <button
            class="generate-btn"
            :disabled="!canGenerate"
            @click="startGeneration"
          >
            <span v-if="status === 'generating'" class="btn-spinner"></span>
            <svg
              v-else
              width="20"
              height="20"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
            </svg>
            <span>{{ status === "generating" ? "生成中..." : "开始生成" }}</span>
          </button>
          <button
            v-if="status === 'done' || status === 'error'"
            class="reset-btn"
            @click="resetAll"
          >
            重新生成
          </button>
        </div>
      </div>

      <!-- Right Panel: Result -->
      <div class="right-panel">
        <!-- Empty State -->
        <div v-if="status === 'idle'" class="empty-state">
          <div class="empty-icon">
            <svg
              width="48"
              height="48"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="1.2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
            </svg>
          </div>
          <p class="empty-title">等待生成</p>
          <p class="empty-hint">在左侧配置参数，点击「开始生成」创建试题</p>
        </div>

        <!-- Result Area -->
        <div
          v-else-if="status === 'generating' || status === 'done'"
          class="result-area"
        >
          <div class="result-header">
            <div class="result-title-wrap">
              <div
                class="result-dot"
                :class="{ pulse: status === 'generating' }"
              ></div>
              <span class="result-title">{{
                status === "generating" ? "AI 正在生成..." : "生成完成"
              }}</span>
            </div>
            <span v-if="parsedQuestions.length > 0" class="question-count-badge">
              已生成 {{ parsedQuestions.length }} 题
            </span>
          </div>

          <div class="questions-list">
            <div
              v-for="(q, idx) in parsedQuestions"
              :key="q.id"
              class="question-card"
              :style="{ animationDelay: `${idx * 0.1}s` }"
            >
              <div class="question-header">
                <div class="question-number">题目 {{ q.id }}</div>
                <div class="question-meta">
                  <span class="meta-tag type-tag">{{ q.type }}</span>
                  <span class="meta-tag difficulty-tag">{{ q.difficulty }}</span>
                </div>
              </div>

              <div class="question-content">
                <p class="content-text">{{ q.content }}</p>
              </div>

              <div v-if="q.options && q.options.length > 0" class="options-grid">
                <div
                  v-for="opt in q.options"
                  :key="opt.label"
                  class="option-item"
                >
                  <span class="option-label">{{ opt.label }}.</span>
                  <span class="option-text">{{ opt.content }}</span>
                </div>
              </div>

              <div class="answer-section">
                <div class="answer-row">
                  <span class="answer-label">正确答案：</span>
                  <span class="answer-value">{{ q.answer }}</span>
                </div>
              </div>

              <div class="explanation-section">
                <div class="explanation-header">
                  <svg
                    width="16"
                    height="16"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                  >
                    <circle cx="12" cy="12" r="10" />
                    <line x1="12" y1="16" x2="12" y2="12" />
                    <line x1="12" y1="8" x2="12.01" y2="8" />
                  </svg>
                  <span>解析</span>
                </div>
                <p class="explanation-text">{{ q.explanation }}</p>
              </div>

              <div class="knowledge-section">
                <span class="knowledge-label">知识点：</span>
                <span class="knowledge-value">{{ q.knowledgePoint }}</span>
              </div>
            </div>

            <!-- 生成中的占位符 -->
            <div v-if="status === 'generating'" class="loading-card">
              <div class="loading-dots">
                <span class="dot"></span>
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
              <p class="loading-text">正在生成试题，请稍候...</p>
            </div>
          </div>
        </div>

        <!-- Error State -->
        <div v-else-if="status === 'error'" class="empty-state error-state">
          <div class="empty-icon error-icon">
            <svg
              width="48"
              height="48"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="1.2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <circle cx="12" cy="12" r="10" />
              <line x1="12" y1="8" x2="12" y2="12" />
              <line x1="12" y1="16" x2="12.01" y2="16" />
            </svg>
          </div>
          <p class="empty-title">生成失败</p>
          <p class="empty-hint">请检查网络连接后重试</p>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.page-container {
  height: 100vh;
  overflow: hidden;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  font-family: "Inter", "PingFang SC", -apple-system, sans-serif;
}

/* Nav */
.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.5rem;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--card-border);
  backdrop-filter: blur(12px);
  position: sticky;
  top: 0;
  z-index: 10;
}
.back-btn {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.4rem 0.75rem;
  border-radius: 8px;
  transition: all 0.2s;
}
.back-btn:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
}
.nav-title {
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0;
  background: linear-gradient(135deg, #10b981, #059669);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Main Layout */
.main-layout {
  flex: 1;
  min-height: 0;
  display: flex;
  overflow: hidden;
}

/* Left Panel */
.left-panel {
  width: 380px;
  min-width: 320px;
  max-width: 440px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
  border-right: 1px solid var(--card-border);
  overflow-y: auto;
  flex-shrink: 0;
}

/* Right Panel */
.right-panel {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
}

.right-panel::-webkit-scrollbar {
  width: 8px;
}

.right-panel::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  margin: 4px 0;
}

.right-panel::-webkit-scrollbar-thumb {
  background: rgba(16, 185, 129, 0.3);
  border-radius: 4px;
  transition: background 0.2s;
}

.right-panel::-webkit-scrollbar-thumb:hover {
  background: rgba(16, 185, 129, 0.5);
}

/* Empty State */
.empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: var(--text-secondary);
  opacity: 0.5;
}
.empty-icon {
  color: var(--text-secondary);
  opacity: 0.4;
}
.empty-title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
}
.empty-hint {
  font-size: 0.875rem;
  margin: 0;
  text-align: center;
}
.error-state {
  opacity: 1;
}
.error-icon {
  color: #f87171;
  opacity: 1;
}
.error-state .empty-title {
  color: #fca5a5;
}

/* Error Banner */
.error-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-bottom: 1px solid rgba(239, 68, 68, 0.3);
  padding: 0.75rem 1.5rem;
  color: #fca5a5;
  font-size: 0.9rem;
  animation: fadeInUp 0.2s ease;
  flex-shrink: 0;
}
.error-close {
  background: none;
  border: none;
  color: #fca5a5;
  cursor: pointer;
  font-size: 1rem;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.error-close:hover {
  opacity: 1;
}

/* Config Card */
.config-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--card-border);
  border-radius: 20px;
  overflow: hidden;
  backdrop-filter: blur(12px);
}

.config-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1.25rem;
  border-bottom: 1px solid var(--card-border);
  color: #10b981;
  font-weight: 600;
  font-size: 1rem;
}

.config-body {
  padding: 1.5rem;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  overflow-y: auto;
  min-height: 0;
}

.config-body::-webkit-scrollbar {
  width: 6px;
}

.config-body::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 3px;
}

.config-body::-webkit-scrollbar-thumb {
  background: rgba(16, 185, 129, 0.3);
  border-radius: 3px;
  transition: background 0.2s;
}

.config-body::-webkit-scrollbar-thumb:hover {
  background: rgba(16, 185, 129, 0.5);
}

.config-item {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.config-label {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.count-value {
  font-size: 0.85rem;
  color: #10b981;
  font-weight: 600;
}

/* Difficulty Selection */
.difficulty-group {
  display: flex;
  gap: 0.75rem;
}

.difficulty-btn {
  flex: 1;
  padding: 0.75rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
  transition: all 0.2s;
}
.difficulty-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.05);
  border-color: var(--accent-color);
}
.difficulty-btn.active {
  background: rgba(255, 255, 255, 0.08);
  border-color: var(--accent-color);
  color: var(--accent-color);
}
.difficulty-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Range Slider */
.range-slider {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.range-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  background: #10b981;
  border-radius: 50%;
  cursor: pointer;
  transition: transform 0.2s;
}
.range-slider::-webkit-slider-thumb:hover {
  transform: scale(1.2);
}
.range-slider:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.range-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--text-secondary);
  opacity: 0.6;
}

/* Topic Input */
.topic-input {
  width: 100%;
  padding: 0.875rem 1rem;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  color: var(--text-primary);
  font-size: 0.9rem;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
  box-sizing: border-box;
}
.topic-input::placeholder {
  color: var(--text-secondary);
  opacity: 0.5;
}
.topic-input:focus {
  border-color: rgba(16, 185, 129, 0.5);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}
.topic-input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Select Input */
.select-input {
  width: 100%;
  padding: 0.875rem 1rem;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  color: var(--text-primary);
  font-size: 0.9rem;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
  box-sizing: border-box;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2310b981' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.5rem;
}
.select-input:focus {
  border-color: rgba(16, 185, 129, 0.5);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}
.select-input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.select-input option {
  background: #1a1a2e;
  color: var(--text-primary);
}

/* Knowledge Points Grid */
.knowledge-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.knowledge-btn {
  padding: 0.5rem 0.875rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: 0.8rem;
  cursor: pointer;
  transition: all 0.2s;
}
.knowledge-btn:hover:not(:disabled) {
  background: rgba(16, 185, 129, 0.1);
  border-color: rgba(16, 185, 129, 0.3);
  color: #10b981;
}
.knowledge-btn.active {
  background: rgba(16, 185, 129, 0.15);
  border-color: #10b981;
  color: #10b981;
}
.knowledge-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.mt-2 {
  margin-top: 0.75rem;
}

/* Example Button */
.example-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem;
  background: rgba(16, 185, 129, 0.1);
  border: 1px solid rgba(16, 185, 129, 0.25);
  border-radius: 10px;
  color: #10b981;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.2s;
}
.example-btn:hover:not(:disabled) {
  background: rgba(16, 185, 129, 0.2);
  transform: translateY(-1px);
}
.example-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Generate Button */
.btn-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}
.generate-btn {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: linear-gradient(135deg, #10b981, #059669);
  border: none;
  color: white;
  font-size: 1rem;
  font-weight: 600;
  padding: 0.875rem 2.5rem;
  border-radius: 50px;
  cursor: pointer;
  transition: all 0.25s;
  box-shadow: 0 4px 20px rgba(16, 185, 129, 0.35);
}
.generate-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(16, 185, 129, 0.5);
}
.generate-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}
.reset-btn {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: var(--text-secondary);
  font-size: 0.9rem;
  padding: 0.875rem 1.5rem;
  border-radius: 50px;
  cursor: pointer;
  transition: all 0.2s;
}
.reset-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-primary);
}
.btn-spinner {
  width: 18px;
  height: 18px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* Result Area */
.result-area {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.result-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.result-title-wrap {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.result-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #10b981;
}
.result-dot.pulse {
  animation: pulse 1.2s ease-in-out infinite;
}
.result-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary);
}
.question-count-badge {
  background: rgba(16, 185, 129, 0.15);
  color: #10b981;
  padding: 0.4rem 1rem;
  border-radius: 20px;
  font-size: 0.85rem;
  font-weight: 600;
}

/* Questions List */
.questions-list {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.question-card {
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--card-border);
  border-radius: 16px;
  overflow: hidden;
  animation: fadeInUp 0.4s ease both;
}

.question-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  background: rgba(16, 185, 129, 0.04);
  border-bottom: 1px solid var(--card-border);
}

.question-number {
  font-size: 1rem;
  font-weight: 600;
  color: #10b981;
}

.question-meta {
  display: flex;
  gap: 0.5rem;
}

.meta-tag {
  padding: 0.25rem 0.75rem;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 500;
}

.type-tag {
  background: rgba(16, 185, 129, 0.15);
  color: #10b981;
}

.difficulty-tag {
  background: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
}

.question-content {
  padding: 1.25rem;
}

.content-text {
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--text-primary);
  margin: 0;
  white-space: pre-wrap;
}

.options-grid {
  padding: 0 1.25rem 1.25rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.option-item {
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
}

.option-label {
  font-weight: 600;
  color: #10b981;
  flex-shrink: 0;
}

.option-text {
  color: var(--text-primary);
  font-size: 0.9rem;
}

.answer-section {
  padding: 1rem 1.25rem;
  background: rgba(16, 185, 129, 0.06);
  border-top: 1px solid var(--card-border);
  border-bottom: 1px solid var(--card-border);
}

.answer-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.answer-label {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-secondary);
}

.answer-value {
  font-size: 0.95rem;
  font-weight: 600;
  color: #10b981;
}

.explanation-section {
  padding: 1.25rem;
}

.explanation-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #10b981;
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 0.75rem;
}

.explanation-text {
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--text-secondary);
  margin: 0;
}

.knowledge-section {
  padding: 0.875rem 1.25rem;
  background: rgba(255, 255, 255, 0.02);
  border-top: 1px solid var(--card-border);
}

.knowledge-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-secondary);
}

.knowledge-value {
  font-size: 0.85rem;
  color: var(--text-primary);
}

/* Loading Card */
.loading-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed rgba(16, 185, 129, 0.3);
  border-radius: 16px;
}

.loading-dots {
  display: flex;
  gap: 8px;
  margin-bottom: 1rem;
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(16, 185, 129, 0.4);
  animation: bounce 1.2s ease-in-out infinite;
}

.dot:nth-child(2) {
  animation-delay: 0.2s;
}

.dot:nth-child(3) {
  animation-delay: 0.4s;
}

.loading-text {
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin: 0;
}

/* Animations */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(0.75);
  }
}
@keyframes bounce {
  0%,
  80%,
  100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-6px);
  }
}

@media (max-width: 768px) {
  .main-layout {
    flex-direction: column;
    height: auto;
    overflow: visible;
  }
  .left-panel {
    width: 100%;
    max-width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--card-border);
    overflow-y: visible;
  }
  .right-panel {
    padding: 1.25rem 1rem;
  }
  .options-grid {
    grid-template-columns: 1fr;
  }
}
</style>
