<template>
  <view class="page">
    <!-- 顶部导航栏 -->
    <view class="nav-bar">
      <view class="nav-content">
        <view class="nav-left" @click="goBack">
          <text class="back-icon">←</text>
        </view>
        <text class="page-title">{{ chapterTitle || '章节详情' }}</text>
        <view class="nav-right"></view>
      </view>
    </view>

    <!-- 章节内容 -->
    <scroll-view
      class="chapter-content"
      scroll-y="true"
      :scroll-top="scrollTop"
      :style="{ transform: `translateX(${swipeOffset.value}px)`, transition: swipeTransition.value }"
      @touchstart="onTouchStart"
      @touchmove="onTouchMove"
      @touchend="onTouchEnd"
    >
      <!-- 章节头部信息 -->
      <view class="chapter-header">
    <text class="chapter-num-badge">
      第{{ chapterParentNumber || chapterNumber }}{{ chapterLevel === 2 ? '章 第' + chapterNumber + '节' : '章' }}
    </text>
    <text class="chapter-title-large">{{ chapterTitle }}</text>
        <view class="chapter-meta">
          <text class="word-count">{{ chapterWordCount }}字</text>
          <GenerationStatusBadge v-if="chapterGenStage" :status="chapterGenStage" />
          <view v-if="chapterAudioUrl" class="media-badge audio-badge">
            <text>🎵 音频</text>
          </view>
          <view v-if="chapterVideoUrl" class="media-badge video-badge">
            <text>🎬 视频</text>
          </view>
          <view v-if="isLeafNode" class="edit-toggle-btn" @click="toggleEditMode">
            <text>{{ isEditMode ? '✓ 完成' : '✏️ 编辑' }}</text>
          </view>
          <view v-if="isLeafNode && chapterGenStage !== 'idle' && chapterGenStage !== 'content_generating'" class="regenerate-btn" @click="handleRegenerateContent">
            <text>{{ regeneratingContent ? '生成中...' : '🔄 重新生成' }}</text>
          </view>
        </view>
      </view>

      <!-- 章节内容（level=3小节 或 level=1短文章节） -->
      <!-- 加载中 -->
      <view v-if="isLoading && !chapterContent" class="chapter-body">
        <view class="level-hint-large">
          <text class="hint-icon-large">⏳</text>
          <text class="hint-text-large">正在加载章节内容...</text>
        </view>
      </view>
      <!-- 加载失败 -->
      <view v-else-if="loadError" class="chapter-body">
        <view class="level-hint-large">
          <text class="hint-icon-large">❌</text>
          <text class="hint-text-large">加载章节失败</text>
          <text class="hint-subtext">{{ loadError }}</text>
          <button class="retry-btn" @click="retryLoad">重试</button>
        </view>
      </view>
      <view v-else-if="isLeafNode || (chapterLevel === 1 && chapterContent)" class="chapter-body">
        <!-- 短文类章标识 -->
        <view v-if="chapterLevel === 1 && isLeafNode" class="article-badge">
          <text>📄 短文正文</text>
        </view>
        <!-- 编辑模式 -->
        <view v-if="isEditMode" class="edit-mode">
          <textarea
            v-model="editContent"
            class="content-editor"
            placeholder="编辑章节内容..."
            :maxlength="-1"
          />
          <view class="edit-actions">
            <button class="edit-btn cancel" @click="cancelEdit">取消</button>
            <button class="edit-btn save" @click="saveContent" :disabled="savingContent">
              {{ savingContent ? '保存中...' : '保存' }}
            </button>
          </view>
        </view>
        <!-- 查看模式 -->
        <rich-text v-else :nodes="renderedContent" class="chapter-text"></rich-text>
      </view>

      <!-- 没有内容的非叶节点显示提示 -->
      <view v-else-if="!isLeafNode && !chapterContent" class="chapter-body">
        <view class="level-hint-large">
          <text class="hint-icon-large">📖</text>
          <text class="hint-text-large">这是一个{{ chapterLevel === 1 ? '章' : '节' }}，没有具体内容</text>
          <text v-if="chapterLevel === 2" class="hint-subtext">请点击下方的具体小节查看内容</text>
        </view>
      </view>

      <!-- 底部操作区 -->
      <view class="chapter-actions">
        <!-- 提示：非叶节点显示提示 -->
        <view v-if="!isLeafNode" class="level-hint">
          <text class="hint-icon">💡</text>
          <text class="hint-text">这是一个{{ chapterLevel === 1 ? '章' : '节' }}，请点击具体小节查看内容和生成音频</text>
        </view>

        <!-- 叶节点才能生成音频 -->
        <view v-if="isLeafNode && chapterGenStage === 'content_completed' && !chapterAudioUrl" class="audio-gen-area">
          <button
            v-if="hasEnoughQuota"
            class="action-btn audio-btn"
            :disabled="generatingAudio"
            @click="handleGenerateAudio"
          >
            {{ generatingAudio ? '生成中...' : '🎵 生成音频' }}
          </button>
          <button
            v-else
            class="action-btn upgrade-btn"
            @click="goToSubscription"
          >
            🚀 升级套餐
          </button>
          <view class="quota-info-inline">
            <text class="quota-text">预估消耗 {{ estimatedAudioMinutes }} 分钟</text>
            <text v-if="quotaInfo" class="quota-text">剩余 {{ quotaInfo.remainingMinutes }} 分钟</text>
            <text v-if="!hasEnoughQuota" class="quota-warn">⚠️ 配额不足</text>
          </view>
        </view>
        <!-- 音频生成中状态 -->
        <button
          v-if="isLeafNode && chapterGenStage === 'audio_generating'"
          class="action-btn audio-btn"
          disabled
        >
          🔄 音频生成中...
        </button>
        <!-- 音频失败可重试 -->
        <button
          v-if="isLeafNode && chapterGenStage === 'failed'"
          class="action-btn audio-btn"
          @click="handleGenerateAudio"
        >
          🔄 音频失败，点击重试
        </button>
        <button
          v-if="isLeafNode && chapterGenStage === 'audio_completed' && !chapterVideoUrl"
          class="action-btn video-btn"
          :disabled="generatingVideo"
          @click="handleGenerateVideo"
        >
          {{ generatingVideo ? '生成中...' : '🎬 生成视频' }}
        </button>
        <!-- 视频生成中状态 -->
        <button
          v-if="isLeafNode && chapterGenStage === 'video_generating'"
          class="action-btn video-btn"
          disabled
        >
          🔄 视频生成中...
        </button>
        <!-- 视频失败可重试 -->
        <button
          v-if="isLeafNode && chapterGenStage === 'failed'"
          class="action-btn video-btn"
          @click="handleGenerateVideo"
        >
          🔄 视频失败，点击重试
        </button>

        <!-- 音频播放器按钮 -->
        <view v-if="chapterAudioUrl" class="audio-player">
          <view class="audio-player-header">
            <text class="audio-player-title">🎵 音频播放</text>
            <view v-if="isLeafNode && (chapterGenStage === 'audio_completed' || chapterGenStage === 'audio_generating' || chapterGenStage === 'video_generating' || chapterGenStage === 'video_completed')" class="regenerate-btn" @click="handleRegenerateAudio">
              <text>{{ regeneratingAudio ? '生成中...' : '🔄 重新生成' }}</text>
            </view>
          </view>
          <button class="play-btn" @click="toggleAudio">
            ▶ 播放音频
          </button>
        </view>

        
        <!-- 视频播放器按钮 -->
        <view v-if="chapterVideoUrl" class="video-player">
          <view class="video-player-header">
            <text class="video-player-title">🎬 视频播放</text>
          </view>
          <button class="play-btn video-play-btn" @click="playVideo">
            ▶ 播放视频
          </button>
        </view>

        <!-- 下载区域 -->
        <view v-if="chapterAudioUrl || chapterVideoUrl" class="download-section">
          <view class="download-header">
            <text class="download-title">💾 下载</text>
          </view>
          <view class="download-buttons">
            <button 
              v-if="chapterAudioUrl"
              class="download-btn audio-download"
              @click="downloadAudio"
            >
              🎵 下载音频
            </button>
            <button 
              v-if="chapterVideoUrl"
              class="download-btn video-download"
              @click="downloadVideo"
            >
              🎬 下载视频
            </button>
          </view>
        </view>

        <!-- 发布到平台按钮 -->
        <!-- <view v-if="chapterAudioUrl || chapterVideoUrl" class="publish-section">
          <view class="publish-header">
            <text class="publish-title">🚀 发布到平台</text>
          </view>
          <view class="publish-desc">
            <text>{{ chapterVideoUrl ? '将视频发布到抖音、B站、快手等平台' : '将音频发布到喜马拉雅、蜻蜓FM等平台' }}</text>
          </view>
          <button
            class="publish-btn"
            @click="goToPublish"
          >
            📤 发布{{ chapterVideoUrl ? '视频' : '音频' }}
          </button>
        </view> -->
      </view>

      <!-- 视频播放弹窗 -->
      <view v-if="showVideoModal" class="video-modal">
        <view class="video-modal-mask" @click="closeVideoModal"></view>
        <view class="video-modal-content">
          <view class="video-modal-header">
            <text class="video-modal-title">{{ videoTitle }}</text>
            <view class="video-modal-close" @click="closeVideoModal">×</view>
          </view>
          <video
            :src="videoUrl"
            class="video-player-modal"
            controls
            autoplay
            show-fullscreen-btn
            show-play-btn
            enable-progress-gesture
          ></video>
        </view>
      </view>

      <!-- 章节导航 -->
      <view class="chapter-nav">
        <view
          v-if="prevChapter"
          class="nav-btn prev-btn"
          @click="goToChapter(prevChapter)"
        >
          <text class="nav-arrow">←</text>
          <view class="nav-info">
            <text class="nav-label">上一章</text>
            <text class="nav-title">{{ prevChapter.title }}</text>
          </view>
        </view>
        <view v-else class="nav-btn disabled">
          <text class="nav-label">没有上一章</text>
        </view>

        <view
          v-if="nextChapter"
          class="nav-btn next-btn"
          @click="goToChapter(nextChapter)"
        >
          <view class="nav-info">
            <text class="nav-label">下一章</text>
            <text class="nav-title">{{ nextChapter.title }}</text>
          </view>
          <text class="nav-arrow">→</text>
        </view>
        <view v-else class="nav-btn disabled">
          <text class="nav-label">没有下一章</text>
        </view>
      </view>
    </scroll-view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { onShow, onLoad } from '@dcloudio/uni-app';
import { marked } from 'marked';
import katex from 'katex';
import 'katex/dist/katex.min.css';
import { useAudioStore } from '../../store/audio';
import * as api from '../../utils/book-generator-api';
import { get, put, post } from '../../utils/request';
import type { Book, Chapter } from '../../utils/book-generator-api';
import { useNotificationStore } from '../../store/notification';
import GenerationStatusBadge from '../../components/GenerationStatusBadge.vue';

// scroll-top 用于避免 scrollTop 错误
const scrollTop = ref(0);

// 手势滑动相关
const swipeOffset = ref(0);
const swipeTransition = ref('');
let touchStartX = 0;
const MIN_SWIPE_DISTANCE = 50;

// 配置 marked
marked.setOptions({
  gfm: true,
  breaks: true,
});

// 渲染 LaTeX 数学公式
function renderLatex(text: string): string {
  // 渲染块级公式 $$...$$
  text = text.replace(/\$\$([\s\S]+?)\$\$/g, (_, latex) => {
    try {
      return `<div class="math-block">${katex.renderToString(latex.trim(), { displayMode: true, throwOnError: false })}</div>`;
    } catch (e) {
      return `<div class="math-block math-error">${latex}</div>`;
    }
  });

  // 渲染行内公式 $...$
  text = text.replace(/\$([^\$\n]+?)\$/g, (_, latex) => {
    try {
      return katex.renderToString(latex.trim(), { displayMode: false, throwOnError: false });
    } catch (e) {
      return `<span class="math-error">${latex}</span>`;
    }
  });

  return text;
}

// 渲染 Markdown + LaTeX 内容
function renderContent(content: string): string {
  if (!content) return '';

  // 1. 先渲染 LaTeX 数学公式
  const withLatex = renderLatex(content);

  // 2. 再渲染 Markdown
  const html = marked.parse(withLatex) as string;

  return html;
}

// 渲染后的内容
const renderedContent = computed(() => {
  const content = chapterContent.value;
  if (!content) return '';
  try {
    const html = renderContent(content);
    console.log('[ChapterDetail] renderedContent computed, html length:', html?.length);
    return html;
  } catch (e) {
    console.error('[ChapterDetail] renderedContent 渲染失败:', e);
    // fallback: 直接显示原始文本（做简单换行处理）
    return content.replace(/\n/g, '<br>');
  }
});

const audioStore = useAudioStore();

// 章节信息
const bookId = ref<string>('');
const chapterNumber = ref<number>(0);
const chapterParentNumber = ref<number>(0);
const chapterTitle = ref<string>('');
const chapterContent = ref<string>('');
const chapterWordCount = ref<number>(0);
const chapterStatus = ref<string>('pending');
const chapterGenStage = ref<string>('');
const chapterAudioUrl = ref<string>('');
const chapterVideoUrl = ref<string>('');
const chapterIsPublic = ref<boolean>(false);
const chapterId = ref<number>(0);
const chapterLevel = ref<number>(1);
// 叶节点ID列表（用于判断当前章节是否为叶节点）
const leafChapterIds = ref<string[]>([]);
// 计算属性：判断当前章节是否为叶节点（没有子节点的节点）
const isLeafNode = computed(() => {
  return leafChapterIds.value.includes(String(chapterId.value));
});

// 编辑模式状态
const isEditMode = ref(false);
const editContent = ref('');
const savingContent = ref(false);

// 章节列表（用于上下章导航）
const chapters = ref<Chapter[]>([]);
const prevChapter = ref<Chapter | null>(null);
const nextChapter = ref<Chapter | null>(null);

// 加载状态
const generatingAudio = ref(false);
const generatingVideo = ref(false);
const regeneratingContent = ref(false);
const regeneratingAudio = ref(false);
const togglingPublic = ref(false);
const needsReload = ref(false);
const isLoading = ref(false);
const loadError = ref<string>('');

// 音频播放状态
const isAudioPlaying = ref(false);
const audioCurrentTime = ref('00:00');

// 配额信息
const quotaInfo = ref<{
  totalMinutes: number;
  usedMinutes: number;
  remainingMinutes: number;
  overageEnabled: boolean;
} | null>(null);

const estimatedAudioMinutes = computed(() => {
  const words = chapterWordCount.value || 0;
  return Math.max(1, Math.ceil(words / 150));
});

const hasEnoughQuota = computed(() => {
  if (!quotaInfo.value) return true;
  if (quotaInfo.value.overageEnabled) return true;
  return quotaInfo.value.remainingMinutes >= estimatedAudioMinutes.value;
});

async function fetchQuotaInfo() {
  try {
    const res = await get<{
      totalMinutes: number;
      usedMinutes: number;
      remainingMinutes: number;
      overageEnabled: boolean;
    }>('/subscription/audio-balance');
    if (res) {
      quotaInfo.value = {
        totalMinutes: res.totalMinutes,
        usedMinutes: res.usedMinutes,
        remainingMinutes: res.remainingMinutes,
        overageEnabled: res.overageEnabled,
      };
    }
  } catch {
    quotaInfo.value = null;
  }
}

function goToSubscription() {
  uni.navigateTo({ url: '/pages/subscription/index' });
}
const audioDuration = ref('00:00');

// 轮询定时器 ID
let audioPollTimer: ReturnType<typeof setInterval> | null = null;
let videoPollTimer: ReturnType<typeof setInterval> | null = null;

// 视频播放
const videoUrl = ref('');
const videoTitle = ref('');
const showVideoModal = ref(false);

// 从 URL 获取参数
function getParamsFromUrl(): { bookId: string; chapterNumber: number } | null {
  console.log('[ChapterDetail] getParamsFromUrl called, window.location.hash:', typeof window !== 'undefined' ? window.location.hash : 'N/A');
  if (typeof window !== 'undefined') {
    const hash = window.location.hash;
    // H5 hash 路由格式: #/pages/book-generator/chapter-detail?bookId=114&chapter=3237
    const match = hash.match(/bookId=([^&]+)&chapter=(\d+)/);
    if (match) {
      console.log('[ChapterDetail] getParamsFromUrl found params:', match[1], match[2]);
      return {
        bookId: decodeURIComponent(match[1]),
        chapterNumber: parseInt(match[2], 10)
      };
    }
  }
  console.log('[ChapterDetail] getParamsFromUrl found no params');
  return null;
}

// 播放音频 - 使用统一的 audioStore
function toggleAudio() {
  if (!chapterAudioUrl.value) {
    uni.showToast({ title: '该章节暂无音频', icon: 'none' });
    return;
  }
  
  // 直接使用当前章节的 ID（页面加载时已设置）
  const currentChapterId = chapterId.value;
  
  // 设置播放列表和当前音频，使用 audioStore 播放
  const audioChapters = chapters.value.filter((c) => c.audioUrl);
  const playlist = audioChapters.map((c) => ({
    id: parseInt(c.id),
    title: c.title,
    audioDuration: c.audioDuration || 0,
    wordCount: c.wordCount || 0,
    audioUrl: c.audioUrl,
  }));
  const playIndex = audioChapters.findIndex((c) => c.id === String(currentChapterId));
  
  audioStore.setPlaylist(playlist as any, playIndex >= 0 ? playIndex : 0, true);
  audioStore.play({
    id: currentChapterId,
    title: chapterTitle.value,
    audioDuration: 0,
    wordCount: chapterWordCount.value,
    audioUrl: chapterAudioUrl.value,
  } as any);
  
  // 跳转到播放页面，使用当前章节的真实 ID
  uni.navigateTo({
    url: `/pages/player/index?id=${currentChapterId}`
  });
}

// 播放视频 - 使用弹窗方式
function playVideo() {
  console.log('[Video Play] 点击播放视频');
  console.log('[Video Play] chapterVideoUrl:', chapterVideoUrl.value);
  console.log('[Video Play] chapterTitle:', chapterTitle.value);
  
  if (!chapterVideoUrl.value) {
    console.log('[Video Play] 视频URL为空');
    uni.showToast({ title: '该章节暂无视频', icon: 'none' });
    return;
  }
  // 使用相对路径，依赖 Nginx 代理
  videoUrl.value = chapterVideoUrl.value.startsWith('http') ? chapterVideoUrl.value : chapterVideoUrl.value;
  videoTitle.value = chapterTitle.value;
  showVideoModal.value = true;
  console.log('[Video Play] 打开视频弹窗, videoUrl:', videoUrl.value);
}

function closeVideoModal() {
  showVideoModal.value = false;
  videoUrl.value = '';
  videoTitle.value = '';
}

// 跳转到发布页面
function goToPublish() {
  const params: any = {};
  
  if (chapterVideoUrl.value) {
    // 有视频，发布视频
    // 直接使用 videoUrl 发布（uni.navigateTo 会自动编码，不需要手动 encodeURIComponent）
    uni.navigateTo({ 
      url: `/pages/publish/index?videoUrl=${chapterVideoUrl.value}&title=${chapterTitle.value}` 
    });
  } else if (chapterAudioUrl.value) {
    // 只有音频，发布音频
    uni.navigateTo({ 
      url: `/pages/publish/index?audioId=${chapterId.value}` 
    });
  }
}

// 下载音频
function downloadAudio() {
  if (!chapterAudioUrl.value) return;
  
  const url = chapterAudioUrl.value;
  const filename = `${chapterTitle.value || '音频'}.mp3`;
  
  // #ifdef H5
  // H5 平台：创建下载链接
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.target = '_blank';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  uni.showToast({ title: '开始下载', icon: 'success' });
  // #endif
  
  // #ifndef H5
  // App 平台：下载并保存
  uni.downloadFile({
    url: url,
    success: (res) => {
      if (res.statusCode === 200) {
        uni.saveFile({
          tempFilePath: res.tempFilePath,
          success: (saveRes) => {
            uni.showToast({ title: '保存成功', icon: 'success' });
          },
          fail: () => {
            uni.showToast({ title: '保存失败', icon: 'none' });
          }
        });
      }
    },
    fail: () => {
      uni.showToast({ title: '下载失败', icon: 'none' });
    }
  });
  // #endif
}

// 下载视频
function downloadVideo() {
  if (!chapterVideoUrl.value) return;
  
  const url = chapterVideoUrl.value;
  const filename = `${chapterTitle.value || '视频'}.mp4`;
  
  // #ifdef H5
  // H5 平台：创建下载链接
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.target = '_blank';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  uni.showToast({ title: '开始下载', icon: 'success' });
  // #endif
  
  // #ifndef H5
  // App 平台：下载并保存到相册
  uni.downloadFile({
    url: url,
    success: (res) => {
      if (res.statusCode === 200) {
        uni.saveVideoToPhotosAlbum({
          filePath: res.tempFilePath,
          success: () => {
            uni.showToast({ title: '已保存到相册', icon: 'success' });
          },
          fail: () => {
            uni.showToast({ title: '保存失败', icon: 'none' });
          }
        });
      }
    },
    fail: () => {
      uni.showToast({ title: '下载失败', icon: 'none' });
    }
  });
  // #endif
}

// 切换公开状态
async function togglePublic() {
  if (!chapterId.value || togglingPublic.value) return;
  
  togglingPublic.value = true;
  try {
    const newStatus = !chapterIsPublic.value;
    await put(`/player/audio/${chapterId.value}/public`, { isPublic: newStatus });
    chapterIsPublic.value = newStatus;
    uni.showToast({
      title: newStatus ? '已公开到首页' : '已取消公开',
      icon: 'success'
    });
  } catch (e: any) {
    uni.showToast({
      title: e.message || '操作失败',
      icon: 'none'
    });
  } finally {
    togglingPublic.value = false;
  }
}

// 加载书籍和章节信息
async function loadChapter() {
  // 如果已经有 bookId 和 chapterId，直接加载
  if (bookId.value && chapterId.value) {
    console.log('[ChapterDetail] loadChapter: using existing params, bookId:', bookId.value, 'chapterId:', chapterId.value);
    if (!loadingChapter) {
      await loadChapterWithParams(bookId.value, chapterId.value);
    }
    return;
  }

  // H5 端从 URL hash 获取参数
  const params = getParamsFromUrl();
  if (params) {
    bookId.value = params.bookId;
    chapterId.value = params.chapterNumber;
    await loadChapterWithParams(params.bookId, params.chapterNumber);
    return;
  }

  console.log('[ChapterDetail] loadChapter: no params, bookId:', bookId.value, 'chapterId:', chapterId.value);
  uni.showToast({ title: '参数错误', icon: 'none' });
}

// App 端通过 onLoad 参数加载章节
let loadingChapter = false;
async function loadChapterWithParams(id: string, chapterIdParam: number) {
  if (loadingChapter) return;
  loadingChapter = true;
  isLoading.value = true;
  loadError.value = '';

  console.log('[ChapterDetail] loadChapterWithParams called, bookId:', id, 'chapterIdParam:', chapterIdParam);
  bookId.value = id;

  try {
    // 优先使用全局数据（从列表页跳转）
    const navData = (globalThis as any).__navBookData as Book | undefined;
    if (navData && navData.id === id) {
      chapters.value = navData.chapters || [];
      const parentIds = new Set(chapters.value.map((c: Chapter) => c.parentId));
      leafChapterIds.value = chapters.value
        .filter((c: Chapter) => !parentIds.has(c.id))
        .map((c: Chapter) => c.id);
      const chapter = chapters.value.find((c) => String(c.id) === String(chapterIdParam));
      if (chapter) {
        chapterId.value = parseInt(chapter.id);
        chapterNumber.value = chapter.number;
        chapterTitle.value = chapter.title;
        chapterLevel.value = chapter.level || 1;
        // 如果是节（level=2），找到父章节号
        if (chapter.level === 2) {
          const parent = chapters.value.find((c: Chapter) => c.id === chapter.parentId);
          chapterParentNumber.value = parent ? parent.number : 0;
        }
        chapterWordCount.value = chapter.wordCount || 0;
        chapterGenStage.value = (chapter as any).genStage || '';
        chapterAudioUrl.value = chapter.audioUrl || '';
        chapterVideoUrl.value = chapter.videoUrl || '';
        chapterLevel.value = chapter.level || 1;
        // 如果章节没有 content，继续调用 API 获取
        if (!chapter.content) {
          console.log('[ChapterDetail] navData chapter has no content, fetching via API');
        } else {
          chapterContent.value = chapter.content;
          updatePrevNextChapters();
          isLoading.value = false;
          loadingChapter = false;
          return;
        }
      }
      updatePrevNextChapters();
    }

    // 直接获取章节详情（只返回当前章节，不返回整书内容）
    const chapterData = await get<any>(`/book-generator/albums/chapters/${chapterIdParam}`);
    console.log('[ChapterDetail] chapter loaded via API:', chapterData);

    if (!chapterData) {
      throw new Error('章节数据为空');
    }

    chapterId.value = parseInt(chapterData.id);
    chapterNumber.value = chapterData.number;
    chapterTitle.value = chapterData.title;
    chapterContent.value = chapterData.content || '章节内容正在生成中...';
    chapterWordCount.value = chapterData.wordCount || 0;
    chapterGenStage.value = (chapterData as any).genStage || '';
    chapterAudioUrl.value = chapterData.audioUrl || '';
    chapterVideoUrl.value = chapterData.videoUrl || '';
    chapterLevel.value = chapterData.level || 1;

    // 获取章节列表（用于上下章导航 + 找父节点编号）
    const book = await api.getBook(id);
    // 如果是节（level=2），找到父章节号
    if (chapterData.level === 2) {
      const parent = (book?.chapters || []).find((c: any) => c.id === chapterData.parentId);
      chapterParentNumber.value = parent ? parent.number : 0;
    }
    chapters.value = book.chapters || [];
    const parentIds = new Set(chapters.value.map((c: Chapter) => c.parentId));
    leafChapterIds.value = chapters.value
      .filter((c: Chapter) => !parentIds.has(c.id))
      .map((c: Chapter) => c.id);

    // 从 API 获取公开状态
    if (chapterData.audioUrl && chapterId.value) {
      try {
        const audioDetail = await get<{ isPublic?: boolean }>(`/player/audio/${chapterId.value}`);
        if (audioDetail) {
          chapterIsPublic.value = audioDetail.isPublic || false;
        }
      } catch (e) {
        console.log('获取公开状态失败:', e);
      }
    }

    updatePrevNextChapters();
  } catch (e) {
    uni.hideToast();
    const errMsg = e instanceof Error ? e.message : '网络请求失败';
    console.error('[ChapterDetail] 加载章节失败, bookId:', id, 'chapterIdParam:', chapterIdParam, 'error:', errMsg);
    loadError.value = errMsg;
    uni.showToast({ title: '加载失败', icon: 'none', duration: 2000 });
  } finally {
    loadingChapter = false;
    isLoading.value = false;
  }
}

// 更新上下章信息
function updatePrevNextChapters() {
  // 使用ID查找当前章节的索引
  const currentIndex = chapters.value.findIndex(c => c.id === String(chapterId.value));
  prevChapter.value = currentIndex > 0 ? chapters.value[currentIndex - 1] : null;
  nextChapter.value = currentIndex < chapters.value.length - 1 ? chapters.value[currentIndex + 1] : null;
}

function retryLoad() {
  console.log('[ChapterDetail] retryLoad');
  loadChapterWithParams(bookId.value, chapterId.value);
}

function goBack() {
  // 使用 uni.navigateBack 优先，保持 uni-app 页面栈一致性
  const pages = getCurrentPages();
  if (pages.length > 1) {
    uni.navigateBack();
  } else {
    // 页面栈只有当前页面（可能是直接访问 URL），返回书籍详情或列表
    if (bookId.value) {
      uni.redirectTo({
        url: `/pages/book-generator/detail?id=${encodeURIComponent(bookId.value)}`
      });
    } else {
      uni.reLaunch({
        url: '/pages/book-generator/index'
      });
    }
  }
}

// 编辑功能
function toggleEditMode() {
  if (isEditMode.value) {
    // 退出编辑模式
    cancelEdit();
  } else {
    // 进入编辑模式
    isEditMode.value = true;
    editContent.value = chapterContent.value;
  }
}

function cancelEdit() {
  isEditMode.value = false;
  editContent.value = '';
}

async function saveContent() {
  if (!editContent.value.trim()) {
    uni.showToast({ title: '内容不能为空', icon: 'none' });
    return;
  }

  savingContent.value = true;
  try {
    uni.showLoading({ title: '保存中...', mask: true });
    
    await post(`/book-generator/langgraph/books/${bookId.value}/chapters/${chapterId.value}/content`, {
      content: editContent.value,
    });
    
    // 更新本地状态
    chapterContent.value = editContent.value;
    chapterWordCount.value = editContent.value.length;
    
    uni.hideLoading();
    uni.showToast({ title: '保存成功', icon: 'success' });
    
    // 退出编辑模式
    isEditMode.value = false;
  } catch (error) {
    uni.hideLoading();
    console.error('[SaveContent] 保存失败:', error);
    uni.showToast({ title: '保存失败', icon: 'none' });
  } finally {
    savingContent.value = false;
  }
}

function goToChapter(chapter: Chapter) {
  uni.redirectTo({
    url: `/pages/book-generator/chapter-detail?bookId=${encodeURIComponent(bookId.value)}&chapter=${chapter.id}`
  });
}

async function handleGenerateAudio() {
  if (generatingAudio.value) return;
  // 配额预检
  if (!hasEnoughQuota.value && quotaInfo.value) {
    uni.showModal({
      title: '配额不足',
      content: `预估消耗 ${estimatedAudioMinutes.value} 分钟，剩余 ${quotaInfo.value.remainingMinutes} 分钟。是否前往升级套餐？`,
      confirmText: '升级套餐',
      cancelText: '取消',
      success: (res) => {
        if (res.confirm) {
          goToSubscription();
        }
      },
    });
    return;
  }
  uni.showModal({
    title: '确认生成音频',
    content: '确定要生成该章节音频吗？',
    success: async (res) => {
      if (!res.confirm) return;
      generatingAudio.value = true;
      audioStatus.value = 'generating';
      try {
        await api.generateChapterAudio(bookId.value, chapterNumber.value, 'cherry');
        uni.showToast({ title: '音频生成任务已启动', icon: 'none', duration: 2000 });
        // 轮询检查音频生成状态
        audioPollTimer = setInterval(async () => {
          try {
            const status = await api.getAudioStatus(bookId.value);
            if (status.allCompleted || status.completed > 0) {
              if (audioPollTimer) {
                clearInterval(audioPollTimer);
                audioPollTimer = null;
              }
              generatingAudio.value = false;
              await loadChapter();
              // 写入通知
              const notifStore = useNotificationStore();
              notifStore.add({ type: 'audio_complete', title: '音频生成完成', message: `《${chapterTitle.value || '章节'}》音频已生成完毕`, bookId: bookId.value });
            }
          } catch (e) {
            console.error('轮询音频状态失败:', e);
          }
        }, 5000);
      } catch (e: any) {
        uni.showToast({ title: e.message || '启动失败', icon: 'none' });
        generatingAudio.value = false;
        audioStatus.value = 'failed';
      }
    },
  });
}

async function handleGenerateVideo() {
  if (generatingVideo.value) return;
  uni.showModal({
    title: '确认生成视频',
    content: '确定要生成该章节视频吗？',
    success: async (res) => {
      if (!res.confirm) return;
      generatingVideo.value = true;
      videoStatus.value = 'generating';
      try {
        await api.generateChapterVideo(bookId.value, chapterId.value);
        uni.showToast({ title: '视频生成任务已启动', icon: 'none', duration: 2000 });
        // 轮询检查视频生成状态
        videoPollTimer = setInterval(async () => {
          try {
            const status = await api.getVideoStatus(bookId.value);
            if (status.allCompleted || status.completed > 0) {
              if (videoPollTimer) {
                clearInterval(videoPollTimer);
                videoPollTimer = null;
              }
              generatingVideo.value = false;
              await loadChapter();
              // 写入通知
              const notifStore = useNotificationStore();
              notifStore.add({ type: 'video_complete', title: '视频生成完成', message: `《${chapterTitle.value || '章节'}》视频已生成完毕`, bookId: bookId.value });
            }
          } catch (e) {
            console.error('轮询视频状态失败:', e);
          }
        }, 5000);
      } catch (e: any) {
        uni.showToast({ title: e.message || '启动失败', icon: 'none' });
        generatingVideo.value = false;
        videoStatus.value = 'failed';
      }
    },
  });
}

async function handleRegenerateContent() {
  if (!chapterId.value || regeneratingContent.value) return;

  uni.showModal({
    title: '确认重新生成',
    content: '确定要重新生成该章节内容吗？这将清除当前内容并重新生成。',
    confirmText: '重新生成',
    cancelText: '取消',
    success: async (res) => {
      if (res.confirm) {
        regeneratingContent.value = true;
        try {
          await api.regenerateChapterContent(bookId.value, chapterId.value);
          uni.showToast({ title: '重新生成任务已启动', icon: 'none', duration: 2000 });
          setTimeout(async () => {
            await loadChapter();
          }, 3000);
        } catch (e: any) {
          uni.showToast({ title: e.message || '重新生成失败', icon: 'none' });
        } finally {
          regeneratingContent.value = false;
        }
      }
    }
  });
}

async function handleRegenerateAudio() {
  if (!chapterId.value || regeneratingAudio.value) return;

  uni.showModal({
    title: '确认重新生成音频',
    content: '确定要重新生成该章节音频吗？这将清除当前音频并重新生成。',
    confirmText: '重新生成',
    cancelText: '取消',
    success: async (res) => {
      if (res.confirm) {
        regeneratingAudio.value = true;
        try {
          await api.regenerateChapterAudio(bookId.value, chapterId.value);
          uni.showToast({ title: '音频重新生成任务已启动', icon: 'none', duration: 2000 });
          setTimeout(async () => {
            await loadChapter();
          }, 3000);
        } catch (e: any) {
          uni.showToast({ title: e.message || '重新生成失败', icon: 'none' });
        } finally {
          regeneratingAudio.value = false;
        }
      }
    }
  });
}

// 手势滑动处理
function onTouchStart(e: TouchEvent) {
  touchStartX = e.touches[0].clientX;
  swipeTransition.value = ''; // 拖动时不使用过渡
}

function onTouchMove(e: TouchEvent) {
  const deltaX = e.touches[0].clientX - touchStartX;
  swipeOffset.value = deltaX * 0.3; // 阻尼效果
}

function onTouchEnd(e: TouchEvent) {
  const deltaX = e.changedTouches[0].clientX - touchStartX;
  swipeOffset.value = 0;
  swipeTransition.value = 'transform 0.3s ease-out';

  if (deltaX < -MIN_SWIPE_DISTANCE && nextChapter.value) {
    // 左滑 → 下一章
    goToChapter(nextChapter.value);
  } else if (deltaX > MIN_SWIPE_DISTANCE && prevChapter.value) {
    // 右滑 → 上一章
    goToChapter(prevChapter.value);
  }
}

onMounted(() => {
  console.log('[ChapterDetail] onMounted, bookId:', bookId.value, 'chapterId:', chapterId.value);
  // 如果还没有参数，从 URL 获取
  if (!bookId.value || !chapterId.value) {
    const params = getParamsFromUrl();
    if (params) {
      bookId.value = params.bookId;
      chapterId.value = params.chapterNumber;
    }
  }
  // 如果有参数就加载
  if (bookId.value && chapterId.value) {
    loadChapter();
  }
  // 获取配额信息
  fetchQuotaInfo();
});

onShow(() => {
  // onShow 时从 URL 获取最新参数并加载
  console.log('[ChapterDetail] onShow, bookId:', bookId.value, 'chapterId:', chapterId.value);
  const params = getParamsFromUrl();
  if (params) {
    bookId.value = params.bookId;
    chapterId.value = params.chapterNumber;
  }
  if (bookId.value && chapterId.value) {
    loadChapter();
  }
  // 刷新配额信息
  fetchQuotaInfo();
});

onLoad((query: any) => {
  console.log('[ChapterDetail] onLoad, query:', query);
  // APP 环境使用 onLoad 的 query 参数
  if (query?.bookId && query?.chapter) {
    bookId.value = query.bookId;
    chapterId.value = parseInt(query.chapter);
    loadChapter();
  }
  // H5 环境由 onMounted 从 hash 获取参数
});

// 页面卸载时清理资源
onUnmounted(() => {
  // 清理轮询定时器
  if (audioPollTimer) {
    clearInterval(audioPollTimer);
    audioPollTimer = null;
  }
  if (videoPollTimer) {
    clearInterval(videoPollTimer);
    videoPollTimer = null;
  }
});
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f9fafb;
}

.nav-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.nav-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 88rpx;
  padding: 0 32rpx;
  padding-top: env(safe-area-inset-top);
}

.nav-left, .nav-right { width: 80rpx; }
.back-icon { font-size: 40rpx; color: #1f2937; }
.page-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #1f2937;
  max-width: 400rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chapter-content {
  height: 100vh;
  padding-top: calc(88rpx + env(safe-area-inset-top));
}

.chapter-header {
  padding: 32rpx;
  background: #ffffff;
  margin-bottom: 16rpx;
}

.chapter-num-badge {
  display: inline-block;
  font-size: 24rpx;
  font-weight: 600;
  color: #ffffff;
  background: #4f46e5;
  padding: 6rpx 16rpx;
  border-radius: 8rpx;
  margin-bottom: 16rpx;
}

.chapter-title-large {
  display: block;
  font-size: 40rpx;
  font-weight: 700;
  color: #1f2937;
  margin-bottom: 16rpx;
  line-height: 1.3;
}

.chapter-meta {
  display: flex;
  align-items: center;
  gap: 16rpx;
  flex-wrap: wrap;
}

.word-count { font-size: 26rpx; color: #9ca3af; }
.media-badge { padding: 6rpx 16rpx; border-radius: 8rpx; font-size: 24rpx; }
.audio-badge { background: rgba(16, 185, 129, 0.1); color: #059669; }
.video-badge { background: rgba(245, 158, 11, 0.1); color: #f5576c; }

.article-badge {
  display: inline-block;
  padding: 8rpx 20rpx;
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  color: white;
  border-radius: 16rpx;
  font-size: 24rpx;
  font-weight: 500;
  margin-bottom: 24rpx;
}

.edit-toggle-btn {
  padding: 6rpx 16rpx;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 8rpx;
  font-size: 24rpx;
}

.regenerate-btn {
  padding: 6rpx 16rpx;
  background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
  color: white;
  border-radius: 8rpx;
  font-size: 24rpx;
}

.edit-mode {
  padding: 24rpx;
}

.content-editor {
  width: 100%;
  min-height: 600rpx;
  padding: 24rpx;
  background: #f9fafb;
  border: 2rpx solid #e5e7eb;
  border-radius: 12rpx;
  font-size: 28rpx;
  line-height: 1.8;
}

.edit-actions {
  display: flex;
  gap: 16rpx;
  margin-top: 24rpx;
}

.edit-btn {
  flex: 1;
  padding: 24rpx;
  border-radius: 12rpx;
  font-size: 28rpx;
}

.edit-btn.cancel {
  background: #f3f4f6;
  color: #6b7280;
}

.edit-btn.save {
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: white;
}

.edit-btn.save[disabled] {
  opacity: 0.5;
}

.chapter-body {
  background: #ffffff;
  padding: 32rpx;
  margin-bottom: 16rpx;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.chapter-text {
  font-size: 30rpx;
  line-height: 1.8;
  color: #374151;
  word-break: break-word;
}

/* 数学公式样式 */
.chapter-text :deep(.math-block) {
  margin: 24rpx 0;
  padding: 16rpx;
  overflow-x: auto;
  text-align: center;
  background: rgba(79, 70, 229, 0.05);
  border-radius: 8rpx;
}

.chapter-text :deep(.katex) {
  font-size: 1.1em;
}

.chapter-text :deep(.katex-display) {
  margin: 0;
  padding: 16rpx 0;
}

.chapter-text :deep(.math-error) {
  color: #dc2626;
  background: rgba(220, 38, 38, 0.1);
  padding: 4rpx 8rpx;
  border-radius: 4rpx;
}

/* Markdown 样式 */
.chapter-text :deep(h1) {
  font-size: 36rpx;
  font-weight: 700;
  margin: 32rpx 0 16rpx;
  color: #1f2937;
}

.chapter-text :deep(h2) {
  font-size: 32rpx;
  font-weight: 600;
  margin: 28rpx 0 14rpx;
  color: #1f2937;
}

.chapter-text :deep(h3) {
  font-size: 28rpx;
  font-weight: 600;
  margin: 24rpx 0 12rpx;
  color: #374151;
}

.chapter-text :deep(p) {
  margin: 16rpx 0;
  line-height: 1.8;
}

.chapter-text :deep(ul),
.chapter-text :deep(ol) {
  padding-left: 32rpx;
  margin: 16rpx 0;
}

.chapter-text :deep(li) {
  margin: 8rpx 0;
  line-height: 1.6;
}

.chapter-text :deep(strong) {
  font-weight: 600;
  color: #1f2937;
}

.chapter-text :deep(em) {
  font-style: italic;
}

.chapter-text :deep(blockquote) {
  border-left: 4rpx solid #ddd;
  padding-left: 24rpx;
  margin: 24rpx 0;
  color: #666;
}

.chapter-text :deep(pre) {
  background: #f4f4f4;
  padding: 24rpx;
  border-radius: 8rpx;
  overflow-x: auto;
  margin: 16rpx 0;
}

.chapter-text :deep(code) {
  background: #f4f4f4;
  padding: 4rpx 8rpx;
  border-radius: 4rpx;
  font-size: 26rpx;
}

.chapter-text :deep(img) {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}

.chapter-actions {
  padding: 32rpx;
  background: #ffffff;
  margin-bottom: 16rpx;
}

.level-hint {
  display: flex;
  align-items: center;
  gap: 12rpx;
  padding: 24rpx;
  background: rgba(79, 70, 229, 0.05);
  border: 1px solid rgba(79, 70, 229, 0.2);
  border-radius: 12rpx;
  margin-bottom: 20rpx;
}

.level-hint-large {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 120rpx 40rpx;
  text-align: center;
}

.hint-icon-large {
  font-size: 120rpx;
  margin-bottom: 32rpx;
}

.hint-text-large {
  font-size: 32rpx;
  color: #333;
  font-weight: 500;
  margin-bottom: 16rpx;
}

.retry-btn {
  margin-top: 32rpx;
  padding: 16rpx 48rpx;
  background: #4f46e5;
  color: #fff;
  border-radius: 12rpx;
  font-size: 28rpx;
}

.hint-subtext {
  font-size: 26rpx;
  color: #999;
}

.hint-icon {
  font-size: 32rpx;
}

.hint-text {
  font-size: 26rpx;
  color: #4f46e5;
  line-height: 1.5;
}

.action-btn {
  width: 100%;
  height: 88rpx;
  border-radius: 16rpx;
  font-size: 28rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  margin-bottom: 20rpx;
}

.action-btn.audio-btn { background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #ffffff; }
.action-btn.upgrade-btn { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); color: #ffffff; }
.audio-gen-area { display: flex; flex-direction: column; gap: 8rpx; }
.quota-info-inline { display: flex; flex-wrap: wrap; gap: 12rpx; padding: 8rpx 0; }
.quota-text { font-size: 22rpx; color: #6b7280; }
.quota-warn { font-size: 22rpx; color: #ef4444; font-weight: 600; }
.action-btn.video-btn { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: #ffffff; }
.action-btn[disabled] { opacity: 0.6; }

.audio-player, .video-player {
  margin-top: 24rpx;
  padding: 24rpx;
  border-radius: 16rpx;
}

.audio-player {
  background: rgba(16, 185, 129, 0.05);
  border: 1px solid rgba(16, 185, 129, 0.2);
}

.video-player {
  background: rgba(245, 158, 11, 0.05);
  border: 1px solid rgba(245, 158, 11, 0.2);
}

.audio-player-header, .video-player-header {
  margin-bottom: 16rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.audio-player-title { font-size: 28rpx; font-weight: 600; color: #059669; }
.video-player-title { font-size: 28rpx; font-weight: 600; color: #f5576c; }

.audio-controls {
  display: flex;
  align-items: center;
  gap: 20rpx;
}

.play-btn {
  padding: 16rpx 32rpx;
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  color: #ffffff;
  border-radius: 12rpx;
  font-size: 28rpx;
  border: none;
}

.video-play-btn { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.audio-time { font-size: 26rpx; color: #6b7280; }

/* 公开设置按钮 */
.public-toggle {
  margin-top: 24rpx;
  padding: 24rpx;
  background: rgba(79, 70, 229, 0.05);
  border: 1px solid rgba(79, 70, 229, 0.2);
  border-radius: 16rpx;
}

.public-toggle-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12rpx;
}

.public-toggle-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #4f46e5;
}

.public-toggle-status {
  padding: 6rpx 16rpx;
  border-radius: 20rpx;
  font-size: 24rpx;
}

.status-public {
  background: rgba(16, 185, 129, 0.1);
  color: #059669;
}

.status-private {
  background: rgba(156, 163, 175, 0.1);
  color: #6b7280;
}

.public-toggle-desc {
  font-size: 24rpx;
  color: #6b7280;
  margin-bottom: 20rpx;
  line-height: 1.5;
}

.public-toggle-btn {
  width: 100%;
  height: 80rpx;
  border-radius: 12rpx;
  font-size: 28rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
}

.public-toggle-btn[disabled] {
  opacity: 0.6;
}

.btn-public {
  background: linear-gradient(135deg, #4f46e5 0%, #6366f1 100%);
  color: #ffffff;
}

.btn-cancel {
  background: linear-gradient(135deg, #6b7280 0%, #9ca3af 100%);
  color: #ffffff;
}

/* 发布区域 */
/* 下载区域 */
.download-section {
  margin-top: 24rpx;
  padding: 24rpx;
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.05) 0%, rgba(5, 150, 105, 0.05) 100%);
  border: 1px solid rgba(16, 185, 129, 0.2);
  border-radius: 16rpx;
}

.download-header {
  margin-bottom: 16rpx;
}

.download-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
}

.download-buttons {
  display: flex;
  gap: 16rpx;
}

.download-btn {
  flex: 1;
  height: 72rpx;
  line-height: 72rpx;
  font-size: 26rpx;
  font-weight: 500;
  border-radius: 12rpx;
  border: none;
  transition: all 0.3s;
}

.audio-download {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.video-download {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  color: white;
}

.download-btn:active {
  transform: scale(0.98);
  opacity: 0.9;
}

/* 发布区域 */
.publish-section {
  margin-top: 24rpx;
  padding: 24rpx;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
  border: 1px solid rgba(102, 126, 234, 0.2);
  border-radius: 16rpx;
}

.publish-header {
  margin-bottom: 12rpx;
}

.publish-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #4f46e5;
}

.publish-desc {
  font-size: 24rpx;
  color: #6b7280;
  margin-bottom: 20rpx;
  line-height: 1.5;
}

.publish-btn {
  width: 100%;
  height: 80rpx;
  border-radius: 12rpx;
  font-size: 28rpx;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #ffffff;
}

.chapter-nav {
  display: flex;
  justify-content: space-between;
  padding: 32rpx;
  background: #ffffff;
  margin-bottom: 40rpx;
}

.nav-btn {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12rpx;
  padding: 20rpx;
  background: #f9fafb;
  border-radius: 12rpx;
}

.nav-btn.disabled { opacity: 0.5; justify-content: center; }
.nav-btn.prev-btn { margin-right: 16rpx; }
.nav-btn.next-btn { justify-content: flex-end; margin-left: 16rpx; }

.nav-info { display: flex; flex-direction: column; flex: 1; overflow: hidden; }
.nav-arrow { font-size: 28rpx; color: #4f46e5; flex-shrink: 0; }
.nav-label { font-size: 24rpx; color: #6b7280; }
.nav-title {
  font-size: 26rpx;
  color: #1f2937;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 视频播放弹窗 */
.video-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.video-modal-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
}

.video-modal-content {
  position: relative;
  width: 90%;
  max-width: 800rpx;
  background: #1a1a1a;
  border-radius: 24rpx;
  overflow: hidden;
}

.video-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24rpx 32rpx;
  background: #2a2a2a;
}

.video-modal-title {
  font-size: 28rpx;
  color: #ffffff;
  font-weight: 500;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.video-modal-close {
  width: 48rpx;
  height: 48rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40rpx;
  color: #999;
  margin-left: 16rpx;
}

.video-player-modal {
  width: 100%;
  display: block;
}
</style>
