<template>
  <view class="page">
    <!-- 顶部导航栏 -->
    <view class="nav-bar">
      <view class="nav-content">
        <view class="nav-left" @click="goBack" v-if="showBackButton">
          <text class="back-icon">←</text>
        </view>
        <text class="page-title">书籍生成</text>
        <view class="nav-right">
          <text class="nav-btn" @click="switchTab">📚</text>
        </view>
      </view>
    </view>

    <!-- 主内容区 -->
    <view class="main-content">
      <!-- 书籍列表 -->
      <view class="create-card" @click="goToCreate">
        <text class="create-icon">+</text>
        <text class="create-text">创建新书籍</text>
      </view>

      
      <!-- 书籍列表 -->
      <view v-if="books.length > 0" class="book-list">
          <view
            v-for="book in books"
            :key="book.id"
            class="book-card"
          >
            <view class="book-header" @click="openBook(book)">
              <text class="book-title">{{ book.title }}</text>
              <view class="header-right">
                <text class="edit-icon" @click.stop="goToEdit(book)">✏️</text>
                <GenerationStatusBadge :status="book.isPublished ? 'published' : (book.genStage || book.status || 'draft')"></GenerationStatusBadge>
              </view>
            </view>
            <text class="book-desc" @click="openBook(book)">{{ book.description }}</text>
            <view class="book-meta" @click="openBook(book)">
              <text>{{ book.totalChapters }}章</text>
              <text v-if="book.progress > 0">{{ book.progress }}%</text>
            </view>
            <view v-if="book.progress > 0 && book.progress < 100" class="progress-bar" @click="openBook(book)">
              <view class="progress-fill" :style="{ width: book.progress + '%' }"></view>
            </view>
            <!-- 操作按钮区域 - 2个主导按钮 + 更多下拉菜单 -->
            <view v-if="book.chapters && book.chapters.length > 0" class="book-actions">
              <!-- 主按钮1: 生成内容 / 停止生成 -->
              <button
                class="primary-btn"
                :disabled="generatingAudio[book.id] && !stoppingAudio[book.id]"
                @click.stop="generatingAudio[book.id] ? handleStopAudioGeneration(book) : handleGenerateAllAudio(book)"
              >
                <text v-if="stoppingAudio[book.id]">⏸ 停止中...</text>
                <text v-else-if="generatingAudio[book.id]">⏹ 停止生成</text>
                <text v-else-if="getBookAudioStatus(book).status === 'completed'">🔄 重新生成音频</text>
                <text v-else-if="getBookAudioStatus(book).status === 'partial'">🎵 继续生成({{ getBookAudioStatus(book).completed }}/{{ getBookAudioStatus(book).total }})</text>
                <text v-else>🎵 生成内容</text>
              </button>
              <!-- 主按钮2: 公开/取消公开 -->
              <button
                class="publish-btn"
                :disabled="togglingPublish[book.id]"
                @click.stop="handleTogglePublish(book)"
              >
                {{ togglingPublish[book.id] ? '处理中...' : (book.isPublished ? '🔒 取消公开' : '🌐 公开书籍') }}
              </button>
              <!-- 更多按钮 -->
              <button
                class="more-btn"
                @click.stop="showMoreActions(book)"
              >
                ···
              </button>
            </view>
          </view>
        </view>

        <!-- 空状态 -->
        <view v-else class="empty-state">
          <text class="empty-icon">📖</text>
          <text class="empty-text">暂无书籍</text>
          <text class="empty-hint">点击上方按钮创建第一本书</text>
        </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import * as api from '../../utils/book-generator-api';
import type { Book } from '../../utils/book-generator-api';
import { useNotificationStore } from '../../store/notification';
import GenerationStatusBadge from '../../components/GenerationStatusBadge.vue';

// Tab 页标识
const isTabPage = ref(true);

// 是否显示返回按钮（Tab 页隐藏，非 Tab 页显示）
const showBackButton = computed(() => {
  if (!isTabPage.value) return true;
  const pages = getCurrentPages();
  return pages.length > 1;
});

// 书籍列表
const books = ref<Book[]>([]);
const isLoadingBooks = ref(false);

// 音频/视频生成状态
const generatingAudio = ref<Record<string, boolean> >({});
const generatingVideo = ref<Record<string, boolean> >({});
const mergingAudio = ref<Record<string, boolean> >({});
const mergingVideo = ref<Record<string, boolean> >({});
const togglingPublish = ref<Record<string, boolean> >({});
const stoppingAudio = ref<Record<string, boolean> >({});

// 轮询定时器
const audioPollTimers = ref<Record<string, ReturnType<typeof setInterval>>>({});
const videoPollTimers = ref<Record<string, ReturnType<typeof setInterval>>>({});

function goBack() {
  const pages = getCurrentPages();
  if (pages.length > 1) {
    uni.navigateBack();
  } else {
    uni.switchTab({ url: '/pages/index/index' });
  }
}

function switchTab() {
  uni.switchTab({ url: '/pages/book-generator/index' });
}

function goToCreate() {
  uni.navigateTo({ url: '/pages/book-generator/create' });
}

function goToVideoGenerator() {
  uni.navigateTo({ url: '/pages/video-generator/index' });
}

function getBookLeafLevel(book: Book): number {
  const chapters = book.chapters || [];
  if (chapters.length === 0) return 0;
  const maxLevel = Math.max(...chapters.map(c => c.level || 0));
  return maxLevel > 0 ? maxLevel : 1;
}

function getBookLeafNodes(book: Book, leafLevel: number): any[] {
  return (book.chapters || []).filter(c => c.level === leafLevel);
}

function getBookAudioStatus(book: Book) {
  const leafLevel = getBookLeafLevel(book);
  const leafNodes = getBookLeafNodes(book, leafLevel);
  const total = leafNodes.length;
  // 优先使用 audioStatus 字段，降级到 audioUrl 推断
  const completed = leafNodes.filter(n => {
    if (n.audioStatus === 'completed') return true;
    return !n.audioStatus && n.audioUrl; // 兼容旧数据
  }).length;
  const anyFailed = leafNodes.some(n => n.audioStatus === 'failed');
  const anyProcessing = leafNodes.some(n => n.audioStatus === 'generating' || n.audioStatus === 'processing' || n.audioStatus === 'queued');
  let status: 'none' | 'partial' | 'completed' | 'generating' | 'failed' = 'none';
  if (completed === total && total > 0) status = 'completed';
  else if (anyFailed) status = 'failed';
  else if (anyProcessing || generatingAudio.value[book.id]) status = 'generating';
  else if (completed > 0) status = 'partial';
  return { total, completed, status };
}

function getBookVideoStatus(book: Book) {
  const leafLevel = getBookLeafLevel(book);
  const leafNodes = getBookLeafNodes(book, leafLevel);
  const total = leafNodes.length;
  const completed = leafNodes.filter(n => n.videoUrl).length;
  let status: 'none' | 'partial' | 'completed' | 'generating' = 'none';
  if (completed === total && total > 0) status = 'completed';
  else if (completed > 0) status = 'partial';
  if (generatingVideo.value[book.id]) status = 'generating';
  return { total, completed, status };
}

function canMergeAudio(book: Book): boolean {
  const leafLevel = getBookLeafLevel(book);
  if (leafLevel <= 1) return false;
  const leafNodes = getBookLeafNodes(book, leafLevel);
  return leafNodes.every(n => n.audioUrl) && leafNodes.length > 0;
}

function canMergeVideo(book: Book): boolean {
  const leafLevel = getBookLeafLevel(book);
  if (leafLevel <= 1) return false;
  const leafNodes = getBookLeafNodes(book, leafLevel);
  return leafNodes.every(n => n.videoUrl) && leafNodes.length > 0;
}

async function loadBooks() {
  if (isLoadingBooks.value) return;
  isLoadingBooks.value = true;
  try {
    books.value = await api.getBooks() || [];
  } catch (e) {
    console.error('加载书籍失败:', e);
    books.value = [];
  } finally {
    isLoadingBooks.value = false;
  }
}

async function openBook(book: Book) {
  uni.navigateTo({ url: `/pages/book-generator/detail?id=${book.id}` });
}

function goToEdit(book: Book) {
  uni.navigateTo({ url: `/pages/book-generator/create?editId=${book.id}` });
}

// 辅助函数：清理指定书籍的轮询定时器
function clearAudioPollTimer(bookId: string) {
  if (audioPollTimers.value[bookId]) {
    clearInterval(audioPollTimers.value[bookId]);
    delete audioPollTimers.value[bookId];
  }
}

function clearVideoPollTimer(bookId: string) {
  if (videoPollTimers.value[bookId]) {
    clearInterval(videoPollTimers.value[bookId]);
    delete videoPollTimers.value[bookId];
  }
}

async function handleGenerateAllAudio(book: Book) {
  if (generatingAudio.value[book.id]) return;
  generatingAudio.value[book.id] = true;
  // 清理可能存在的旧定时器
  clearAudioPollTimer(book.id);
  try {
    const result = await api.generateAllChaptersAudio(book.id, 'cherry');
    uni.showToast({ title: `已启动 ${result.totalChapters} 个章节的音频生成`, icon: 'none', duration: 2500 });
    // 开始轮询音频生成状态
    audioPollTimers.value[book.id] = setInterval(async () => {
      try {
        const status = await api.getAudioStatus(book.id);
        if (status.allCompleted) {
          clearAudioPollTimer(book.id);
          generatingAudio.value[book.id] = false;
          await loadBooks();
          uni.showToast({ title: '音频生成完成', icon: 'success' });
          // 写入通知
          const notifStore = useNotificationStore();
          notifStore.add({ type: 'audio_complete', title: '音频生成完成', message: `《${book.title}》音频已全部生成完毕`, bookId: String(book.id) });
        }
      } catch (e) {
        console.error('轮询音频状态失败:', e);
      }
    }, 5000);
  } catch (e: any) {
    clearAudioPollTimer(book.id);
    generatingAudio.value[book.id] = false;
    uni.showToast({ title: e.message || '生成失败', icon: 'none' });
  }
}

async function handleStopAudioGeneration(book: Book) {
  if (!generatingAudio.value[book.id] || stoppingAudio.value[book.id]) return;
  stoppingAudio.value[book.id] = true;
  try {
    await api.cancelAudioGeneration(book.id);
    clearAudioPollTimer(book.id);
    generatingAudio.value[book.id] = false;
    await loadBooks();
    uni.showToast({ title: '已停止音频生成', icon: 'none' });
  } catch (e: any) {
    uni.showToast({ title: e.message || '停止失败', icon: 'none' });
  } finally {
    stoppingAudio.value[book.id] = false;
  }
}

async function handleMergeChapterAudio(book: Book) {
  if (!canMergeAudio(book)) { uni.showToast({ title: '并非所有叶节点音频都已生成完成', icon: 'none' }); return; }
  mergingAudio.value[book.id] = true;
  try {
    const result = await api.mergeChapterAudios(book.id);
    uni.showToast({ title: `已启动音频合并，处理${result.processedParents}个上级章节`, icon: 'none', duration: 2500 });
    setTimeout(async () => { await loadBooks(); mergingAudio.value[book.id] = false; }, 5000);
  } catch (e: any) {
    mergingAudio.value[book.id] = false;
    uni.showToast({ title: e.message || '音频合并失败', icon: 'none' });
  }
}

async function handleMergeChapterVideo(book: Book) {
  if (!canMergeVideo(book)) { uni.showToast({ title: '并非所有叶节点视频都已生成完成', icon: 'none' }); return; }
  mergingVideo.value[book.id] = true;
  try {
    const result = await api.mergeChapterVideos(book.id);
    uni.showToast({ title: `已启动视频合并，处理${result.processedParents}个上级章节`, icon: 'none', duration: 2500 });
    setTimeout(async () => { await loadBooks(); mergingVideo.value[book.id] = false; }, 5000);
  } catch (e: any) {
    mergingVideo.value[book.id] = false;
    uni.showToast({ title: e.message || '视频合并失败', icon: 'none' });
  }
}

async function handleGenerateAllVideo(book: Book) {
  if (generatingVideo.value[book.id]) return;
  uni.showModal({
    title: '确认重新生成视频',
    content: `确定要重新生成《${book.title}》的所有视频吗？这将清除现有视频并重新生成。`,
    success: async (res) => {
      if (!res.confirm) return;
      generatingVideo.value[book.id] = true;
      // 清理可能存在的旧定时器
      clearVideoPollTimer(book.id);
      try {
        const result = await api.generateAllChaptersVideo(book.id);
        uni.showToast({ title: `已启动 ${result.totalChapters} 个章节的视频生成`, icon: 'none', duration: 2500 });
        // 开始轮询视频生成状态
        videoPollTimers.value[book.id] = setInterval(async () => {
          try {
            const status = await api.getVideoStatus(book.id);
            if (status.allCompleted) {
              clearVideoPollTimer(book.id);
              generatingVideo.value[book.id] = false;
              await loadBooks();
              uni.showToast({ title: '视频生成完成', icon: 'success' });
              // 写入通知
              const notifStore = useNotificationStore();
              notifStore.add({ type: 'video_complete', title: '视频生成完成', message: `《${book.title}》视频已全部生成完毕`, bookId: String(book.id) });
            }
          } catch (e) {
            console.error('轮询视频状态失败:', e);
          }
        }, 5000);
      } catch (e: any) {
        clearVideoPollTimer(book.id);
        generatingVideo.value[book.id] = false;
        uni.showToast({ title: e.message || '生成失败', icon: 'none' });
      }
    },
  });
}

async function handleTogglePublish(book: any) {
  togglingPublish.value[book.id] = true;
  try {
    const res = await api.toggleBookPublish(book.id);
    book.isPublished = res.isPublished;
    uni.showToast({ title: book.isPublished ? '已公开到首页' : '已取消公开', icon: 'none' });
  } catch (e: any) {
    uni.showToast({ title: e.message || '操作失败', icon: 'none' });
  } finally {
    togglingPublish.value[book.id] = false;
  }
}

// 显示更多操作菜单
function showMoreActions(book: Book) {
  const audioStatus = getBookAudioStatus(book);
  const videoStatus = getBookVideoStatus(book);
  const actions: string[] = [];

  // 合并音频（音频有完成时才显示）
  if (canMergeAudio(book)) {
    actions.push('🔊 合并音频');
  }
  // 合并视频（视频有完成时才显示）
  if (canMergeVideo(book)) {
    actions.push('🎬 合并视频');
  }
  // 生成全部视频（音频完成且视频未完成或已完成时显示）
  if (audioStatus.status === 'completed' || audioStatus.status === 'none') {
    if (videoStatus.status !== 'completed' || generatingVideo.value[book.id]) {
      actions.push('🎬 生成全部视频');
    }
  }
  // 重新生成视频（视频已完成时显示）
  if (videoStatus.status === 'completed') {
    actions.push('🔄 重新生成视频');
  }
  // 编辑书籍
  actions.push('✏️ 编辑书籍');
  // 删除书籍
  actions.push('🗑 删除书籍');

  // 如果没有可用操作，提示用户
  if (actions.length === 0) {
    uni.showToast({ title: '请先完成音频生成', icon: 'none' });
    return;
  }

  uni.showActionSheet({
    itemList: actions,
    success: (res) => {
      const action = actions[res.tapIndex];
      if (action === '🔊 合并音频') {
        mergingAudio.value[book.id] = true;
        uni.showToast({ title: '正在合并音频...', icon: 'loading', duration: 10000 });
        handleMergeChapterAudio(book);
      } else if (action === '🎬 合并视频') {
        mergingVideo.value[book.id] = true;
        uni.showToast({ title: '正在合并视频...', icon: 'loading', duration: 10000 });
        handleMergeChapterVideo(book);
      } else if (action === '🎬 生成全部视频') {
        handleGenerateAllVideo(book);
      } else if (action === '🔄 重新生成视频') {
        handleGenerateAllVideo(book);
      } else if (action === '✏️ 编辑书籍') {
        goToEdit(book);
      } else if (action === '🗑 删除书籍') {
        handleDeleteBook(book);
      }
    }
  });
}

async function handleDeleteBook(book: Book) {
  uni.showModal({
    title: '确认删除',
    content: `确定要删除《${book.title}》吗？此操作不可恢复。`,
    success: async (res) => {
      if (!res.confirm) return;
      try {
        await api.deleteBook(book.id);
        uni.showToast({ title: '删除成功', icon: 'success' });
        await loadBooks();
      } catch (e: any) {
        uni.showToast({ title: e.message || '删除失败', icon: 'none' });
      }
    }
  });
}

onShow(() => {
  loadBooks();
});

// 初始化
onMounted(() => {
  loadBooks();
});

// 页面卸载时清理所有轮询
onUnmounted(() => {
  // 清理所有轮询定时器
  Object.keys(audioPollTimers.value).forEach(key => clearAudioPollTimer(key));
  Object.keys(videoPollTimers.value).forEach(key => clearVideoPollTimer(key));
});
</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; height: 88rpx; display: flex; align-items: center; justify-content: center; }
.back-icon, .nav-btn { font-size: 40rpx; color: #1f2937; }
.page-title { font-size: 32rpx; font-weight: 600; color: #1f2937; }
.main-content { padding: 120rpx 32rpx 32rpx; }
.card { background: #ffffff; border-radius: 24rpx; padding: 32rpx; margin-bottom: 24rpx; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); }
.create-card { display: flex; align-items: center; justify-content: center; gap: 16rpx; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 24rpx; padding: 48rpx; margin-bottom: 24rpx; }
.create-icon { font-size: 48rpx; color: #ffffff; }
.create-text { font-size: 32rpx; font-weight: 600; color: #ffffff; }
.book-list { display: flex; flex-direction: column; gap: 20rpx; }
.book-card { background: #ffffff; border-radius: 20rpx; padding: 28rpx; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); }
.book-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12rpx; }
.book-title { font-size: 30rpx; font-weight: 600; color: #1f2937; flex: 1; }
.header-right { display: flex; align-items: center; gap: 12rpx; flex-shrink: 0; }
.edit-icon { font-size: 28rpx; padding: 4rpx; opacity: 0.5; }
.edit-icon:active { opacity: 1; }
/* 状态标签由 GenerationStatusBadge 组件统一管理 */
.book-desc { font-size: 26rpx; color: #6b7280; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 16rpx; }
.book-meta { display: flex; gap: 24rpx; font-size: 24rpx; color: #9ca3af; margin-bottom: 12rpx; }
.progress-bar { height: 6rpx; background: #e5e7eb; border-radius: 3rpx; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); border-radius: 3rpx; transition: width 0.3s; }
.book-actions { display: flex; gap: 12rpx; }
.primary-btn, .publish-btn, .more-btn { height: 72rpx; border-radius: 12rpx; font-size: 26rpx; display: flex; align-items: center; justify-content: center; border: none; white-space: nowrap; }
.primary-btn { flex: 1; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #ffffff; padding: 0 16rpx; }
.publish-btn { width: auto; min-width: 160rpx; padding: 0 24rpx; background: linear-gradient(135deg, #4f46e5 0%, #6366f1 100%); color: #ffffff; }
.more-btn { width: 80rpx; background: #e5e7eb; color: #6b7280; font-size: 32rpx; font-weight: bold; }
.more-btn { width: 80rpx; background: #e5e7eb; color: #6b7280; font-size: 32rpx; font-weight: bold; }
.primary-btn[disabled], .publish-btn[disabled], .more-btn[disabled] { opacity: 0.6; }
/* 夜间模式适配 */
@media (prefers-color-scheme: dark) {
  .more-btn { background: #374151; color: #d1d5db; }
  .primary-btn { background: linear-gradient(135deg, #059669 0%, #047857 100%); }
  .publish-btn { background: linear-gradient(135deg, #4338ca 0%, #4f46e5 100%); }
}
.empty-state { display: flex; flex-direction: column; align-items: center; padding: 80rpx 0; }
.empty-icon { font-size: 120rpx; margin-bottom: 24rpx; }
.empty-text { font-size: 32rpx; color: #6b7280; margin-bottom: 12rpx; }
.empty-hint { font-size: 26rpx; color: #9ca3af; }
</style>
