<template>
  <view class="page">
    <!-- 顶部导航 -->
    <view class="nav-bar">
      <view class="nav-btn" @click="goBack">
        <text class="nav-icon">↓</text>
      </view>
      <view class="nav-center">
        <text class="nav-title">正在播放</text>
        <!-- 睡眠定时显示 -->
        <view v-if="sleepTimer" class="sleep-timer-badge" @click="showSleepTimerPicker = true">
          <text class="sleep-timer-icon">⏰</text>
          <text class="sleep-timer-text">{{ formatSleepTimer(sleepTimer.remaining) }}</text>
        </view>
      </view>
      <view class="nav-btn" @click="showSleepTimerPicker = true">
        <text class="nav-icon">⏰</text>
      </view>
    </view>

    <!-- 无音频提示 -->
    <view v-if="!audio?.audioUrl" class="empty-state">
      <text class="empty-icon">🎵</text>
      <text class="empty-title">暂无音频</text>
      <text class="empty-desc">该章节还没有生成音频</text>
      <button class="empty-btn" @click="goBack">返回</button>
    </view>

    <!-- 正常播放界面 -->
    <template v-else>

    <!-- 封面和标题 -->
    <view class="cover-section">
      <view class="cover">
        <text class="cover-icon">🎵</text>
      </view>
      <text class="title">{{ audio?.title || '未知标题' }}</text>
      <text class="meta">{{ formatDuration(duration) }} · {{ audio?.wordCount || 0 }}字</text>
    </view>

    <!-- 文本预览（歌词同步） -->
    <scroll-view
      class="text-preview"
      scroll-y
      :style="{ maxHeight: '300rpx' }"
      :scroll-into-view="scrollIntoViewId"
      scroll-with-animation
    >
      <view class="lyrics-container">
        <view
          v-for="(line, index) in lyrics"
          :key="index"
          :id="'lyric-' + index"
          class="lyric-line"
          :class="{ active: index === currentLyricIndex }"
        >
          <text class="lyric-text">{{ line.text }}</text>
        </view>
      </view>
    </scroll-view>

    <!-- 进度条 -->
    <view class="progress-section">
      <text class="time">{{ formatDuration(currentTime) }}</text>
      <slider
        :value="currentTime"
        :max="duration || 100"
        @change="handleSeek"
        activeColor="#4F46E5"
        backgroundColor="#e5e7eb"
        block-size="16"
        class="progress-slider"
      />
      <text class="time">{{ formatDuration(duration) }}</text>
    </view>

    <!-- 播放控制 -->
    <view class="controls">
      <!-- 左侧按钮：播放速度、下载 -->
      <view class="controls-side">
        <view class="control-btn" @click="showRatePicker = true">
          <text class="control-text">{{ playRate }}x</text>
        </view>
        <AudioDownload
          :url="getFullUrl(audio?.audioUrl || '')"
          :filename="`${audio?.title || 'audio'}.mp3`"
          :audio-id="String(audio?.id || '')"
        >
          <view class="control-btn">
            <text class="control-icon">⬇</text>
          </view>
        </AudioDownload>
      </view>

      <!-- 中间按钮：上一首、播放/暂停、下一首 -->
      <view class="controls-center">
        <view class="control-btn" :class="{ disabled: !hasPrev }" @click="playPrev">
          <text class="control-icon">⏮</text>
        </view>

        <view class="play-btn" @click="togglePlay">
          <text class="play-icon">{{ isPlaying ? '⏸' : '▶' }}</text>
        </view>

        <view class="control-btn" :class="{ disabled: !hasNext }" @click="playNext">
          <text class="control-icon">⏭</text>
        </view>
      </view>

      <!-- 右侧按钮：收藏、分享 -->
      <view class="controls-side">
        <view class="control-btn" @click="toggleFavorite">
          <text class="control-icon">{{ audio?.isFavorite ? '❤️' : '🤍' }}</text>
        </view>
        <view class="control-btn share-btn" @click="handleShare">
          <text class="control-icon">📤</text>
          <text class="share-label">分享得时长</text>
        </view>
      </view>
    </view>

    <!-- 播放列表 - 移动端设计，直接在界面中显示 -->
    <view class="playlist-section-mobile">
      <view class="playlist-header">
        <view class="playlist-header-left">
          <text class="playlist-title">播放列表</text>
          <text class="playlist-count">{{ playlist.length }}首</text>
        </view>
        <view class="playlist-header-right" @click="togglePlayMode">
          <text class="playlist-mode-icon">{{ getPlayModeIcon() }}</text>
          <text class="playlist-mode-text">{{ getPlayModeText() }}</text>
        </view>
      </view>
      <scroll-view class="playlist-list-mobile" scroll-y :style="{ maxHeight: '35vh' }">
        <view
          v-for="(item, index) in playlist"
          :key="item.id"
          :class="['playlist-item', { active: item.id === audio?.id }]"
          @click="playFromPlaylist(index)"
        >
          <view class="playlist-index">{{ index + 1 }}</view>
          <view class="playlist-info">
            <text class="playlist-item-title">{{ item.title }}</text>
            <text class="playlist-item-meta">{{ formatDuration(item.audioDuration || 0) }}</text>
          </view>
          <view v-if="item.id === audio?.id" class="playing-icon">▶</view>
        </view>
      </scroll-view>
    </view>
    </template>

    <!-- 播放速度选择器 -->
    <view v-if="showRatePicker" class="rate-picker" @click="showRatePicker = false">
      <view class="rate-content" @click.stop>
        <text class="rate-title">播放速度</text>
        <view class="rate-options">
          <view
            v-for="rate in [0.5, 0.75, 1, 1.25, 1.5, 2]"
            :key="rate"
            class="rate-item"
            :class="{ active: playRate === rate }"
            @click="handleSetRate(rate)"
          >
            <text>{{ rate }}x</text>
          </view>
        </view>
      </view>
    </view>

    <!-- 睡眠定时选择器 -->
    <view v-if="showSleepTimerPicker" class="rate-picker" @click="showSleepTimerPicker = false">
      <view class="rate-content" @click.stop>
        <text class="rate-title">睡眠定时</text>
        <view class="rate-options">
          <view
            v-for="option in sleepTimerOptions"
            :key="option.value"
            class="rate-item"
            :class="{ active: sleepTimer && sleepTimer.total === option.value }"
            @click="handleSetSleepTimer(option.value)"
          >
            <text>{{ option.label }}</text>
          </view>
        </view>
        <view v-if="sleepTimer" class="sleep-timer-cancel" @click="cancelSleepTimer">
          <text>取消定时</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import { onLoad } from '@dcloudio/uni-app';
import { useAudioStore } from '../../store/audio';
import { get, put, post, getFullUrl } from '../../utils/request';
import { trackEvent, AnalyticsEvents } from '../../utils/analytics';
import type { AudioItem } from '../../types';
import AudioDownload from '../../components/AudioDownload.vue';

// 分享数据接口
interface ShareCardData {
  title: string;
  description: string;
  imageUrl: string;
  shareUrl: string;
  shareCode: string;
  chapterId: number;
  wordCount: number;
  audioDuration: number;
}

const audioStore = useAudioStore();

// 状态
const audioId = ref('');
const audio = ref<AudioItem | null>(null);
const showRatePicker = ref(false);
const showSleepTimerPicker = ref(false);
const lyrics = ref<{ text: string; start: number; end: number }[]>([]);
const scrollIntoViewId = ref('');

// 分享数据
const shareData = ref<ShareCardData | null>(null);

// 睡眠定时
const sleepTimer = ref<{ remaining: number; total: number } | null>(null);
let sleepTimerInterval: ReturnType<typeof setInterval> | null = null;

// 睡眠定时选项
const sleepTimerOptions = [
  { label: '15分钟', value: 15 * 60 },
  { label: '30分钟', value: 30 * 60 },
  { label: '60分钟', value: 60 * 60 },
  { label: '当前播放结束', value: -1 },
];

// 解析 LRC 格式歌词（兼容换行分隔和单行连续两种格式）
function parseLrc(lrcText: string): { text: string; start: number; end: number }[] {
  if (!lrcText) return [];

  const timeline: { text: string; start: number; end: number }[] = [];

  // 优先按换行分割，如果只有1行则用全局匹配提取所有时间戳
  const lines = lrcText.split('\n');
  if (lines.length <= 1) {
    // 单行格式：用正则提取所有 [MM:SS.XX]text 对
    const matches = lrcText.matchAll(/\[(\d{2}):(\d{2})\.(\d{2})\]\s*([^[]*)/g);
    for (const m of matches) {
      const minutes = parseInt(m[1]);
      const seconds = parseInt(m[2]);
      const cs = parseInt(m[3]);
      const text = m[4].trim();
      if (text) {
        timeline.push({ text, start: minutes * 60 + seconds + cs / 100, end: 0 });
      }
    }
  } else {
    // 标准格式：按行处理
    for (const line of lines) {
      const match = line.match(/^\[(\d{2}):(\d{2})\.(\d{2})\]\s*(.*)$/);
      if (match) {
        const text = match[4].trim();
        if (text) {
          timeline.push({
            text,
            start: parseInt(match[1]) * 60 + parseInt(match[2]) + parseInt(match[3]) / 100,
            end: 0,
          });
        }
      }
    }
  }

  // 计算 end 时间（下一句的开始时间）
  for (let i = 0; i < timeline.length - 1; i++) {
    timeline[i].end = timeline[i + 1].start;
  }
  if (timeline.length > 0) {
    const last = timeline[timeline.length - 1];
    last.end = last.start + 5;
  }

  return timeline;
}

// 生成歌词时间线（按 Markdown 段落分段，与后端 generateLrc 降级算法一致）
function generateLyricsTimeline(text: string, totalDuration: number): { text: string; start: number; end: number }[] {
  if (!text || totalDuration <= 0) return [];

  // 按 Markdown 结构分段
  const sections: string[] = [];
  const h1Parts = text.split(/(?=^# )/m);
  for (const h1Part of h1Parts) {
    if (!h1Part.trim()) continue;
    const h2Parts = h1Part.split(/(?=^## )/m);
    for (const h2Part of h2Parts) {
      const trimmed = h2Part.trim();
      if (!trimmed) continue;
      const isHeading = /^#{1,2}\s/.test(trimmed);
      if (isHeading) {
        sections.push(trimmed);
      } else {
        const paras = trimmed.split(/\n{2,}/).filter(p => p.trim());
        for (const para of paras) {
          sections.push(para.trim());
        }
      }
    }
  }
  // 降级：按句号分段
  if (sections.length <= 1) {
    const sentences = text.split(/(?<=[。！？；])\s*/).filter(s => s.trim());
    sections.length = 0;
    sections.push(...sentences);
  }

  // 权重分配：标题 0.3x，正文 1.0x
  const weights = sections.map(s => /^#{1,2}\s/.test(s) ? 0.3 : 1.0);
  const weightedChars = sections.map((s, i) => {
    // 统计所有可见字符（含标点、数字、符号），不只汉字字母
    const chars = s.replace(/\s/g, '').length;
    return chars * weights[i];
  });
  const totalWeighted = weightedChars.reduce((a, b) => a + b, 0);
  if (totalWeighted === 0) return [];

  const timeline: { text: string; start: number; end: number }[] = [];
  let currentTime = 0;
  for (let i = 0; i < sections.length; i++) {
    const ratio = weightedChars[i] / totalWeighted;
    const segDuration = ratio * totalDuration;
    const start = currentTime;
    const end = currentTime + segDuration;
    timeline.push({ text: sections[i], start, end });
    currentTime += segDuration;
    // 标题后加停顿
    if (i < sections.length - 1 && /^#{1,2}\s/.test(sections[i])) {
      currentTime = Math.min(currentTime + 0.5, totalDuration);
    }
  }
  // 修正最后一段
  if (timeline.length > 0) {
    timeline[timeline.length - 1].end = totalDuration;
  }
  return timeline;
}

// 根据当前播放时间获取当前句子索引，并自动滚动
// 滚动到当前行的前一行，确保高亮行上下都有可见文本作为缓冲
const currentLyricIndex = computed(() => {
  const time = currentTime.value;
  const index = lyrics.value.findIndex(l => time >= l.start && time < l.end);
  if (index >= 0) {
    // 滚动到前一行（最小为 0，即缓冲空行），使当前行上下文本都可见
    const scrollIndex = Math.max(0, index - 1);
    scrollIntoViewId.value = 'lyric-' + scrollIndex;
  }
  return index;
});

// 从 store 获取状态
const isPlaying = computed(() => audioStore.isPlaying);
const currentTime = computed(() => audioStore.currentTime);
const duration = computed(() => audioStore.duration);
const playRate = computed(() => audioStore.playRate);
const hasPrev = computed(() => audioStore.hasPrev);
const hasNext = computed(() => audioStore.hasNext);
const playlist = computed(() => audioStore.playlist);

// 页面加载
onMounted(async () => {
  const pages = getCurrentPages();
  const currentPage = pages[pages.length - 1] as any;
  // #ifdef APP-PLUS
  audioId.value = currentPage?.$page?.options?.id || '';
  // #endif
  // #ifndef APP-PLUS
  audioId.value = currentPage?.options?.id || '';
  // #endif

  if (audioId.value) {
    await fetchAudio();
  } else {
    uni.showToast({ title: '没有音频ID参数', icon: 'none' });
  }
});

// 页面显示时刷新音频状态
onShow(() => {
  // 刷新 store 中的当前音频信息
  if (audioStore.currentAudio) {
    audio.value = audioStore.currentAudio;
    // 同步进度条
    if (audioStore.currentTime > 0) {
      currentTime.value = audioStore.currentTime;
    }
    if (audioStore.duration > 0) {
      duration.value = audioStore.duration;
    }
  }
});

// 页面卸载
onUnmounted(() => {
  // 清除睡眠定时器
  if (sleepTimerInterval) {
    clearInterval(sleepTimerInterval);
  }
  // 不销毁音频上下文，保持后台播放
});

// 获取音频详情
async function fetchAudio() {
  try {
    // 获取音频详情
    const result = await get<AudioItem>(`/player/audio/${audioId.value}`);
    audio.value = result;

    // 检查是否有音频URL
    if (!result.audioUrl) {
      uni.showToast({
        title: '该章节没有音频，请先生成音频',
        icon: 'none',
        duration: 2000
      });
      return;
    }

    // 获取播放列表（使用专辑章节列表）
    await fetchAlbumPlaylist(result);

    // 生成歌词时间线（优先使用真实 LRC，否则按句子估算）
    const audioDuration = result.audioDuration || audioStore.duration || 60;
    if (result.lrcLyrics) {
      lyrics.value = parseLrc(result.lrcLyrics);
    } else {
      lyrics.value = generateLyricsTimeline(result.text || '', audioDuration);
    }
    // 在歌词列表前插入空行作为视觉缓冲，确保高亮当前行时前后文都可见
    lyrics.value = [{ text: '', start: 0, end: 0 }, ...lyrics.value];

    // 开始播放（store 中已初始化 audioContext）
    audioStore.play(result);
  } catch (error: any) {
    console.error('获取音频失败:', error);
    uni.showToast({ title: error.message || '音频不存在', icon: 'none' });
  }
}

// 获取专辑播放列表
async function fetchAlbumPlaylist(currentAudio: AudioItem) {
  try {
    // 从音频信息中获取albumId（书籍ID） - 优先从音频对象获取
    let albumId = (currentAudio as any).albumId || (currentAudio as any).bookId;

    // 如果当前音频没有albumId，则尝试从章节信息获取
    if (!albumId) {
      // 由于 we're using chapter ID as audioId, try to get album info from chapters API
      // We'll use the current audioId to get chapter details and then album ID
      try {
        const chapterDetail = await get<any>(`/book-generator/albums/chapters/${audioId.value}`);
        albumId = chapterDetail?.bookId; // The chapter detail now includes bookId
      } catch (err) {
        console.warn('无法通过章节ID获取专辑信息:', err);
      }
    }

    if (!albumId) {
      // 如果还是没有albumId，使用通用播放列表
      await fetchGenericPlaylist();
      return;
    }

    // 获取专辑章节列表
    const data = await get<{ chapters: any[] }>(`/book-generator/albums/${albumId}/chapters`);
    const chapters = data?.chapters || [];

    // 转换为播放列表格式
    const playlist = chapters
      .filter((c: any) => c.audioUrl) // 只包含有音频的章节
      .map((c: any) => ({
        _id: c.id,
        id: c.id,
        title: c.title,
        audioUrl: c.audioUrl,
        audioDuration: c.audioDuration || 0,
        wordCount: c.wordCount || 0,
      }));

    // 找到当前音频在列表中的位置
    const currentIndex = playlist.findIndex(item => item.id === audioId.value);

    if (playlist.length > 0) {
      audioStore.setPlaylist(playlist, currentIndex >= 0 ? currentIndex : 0, true);
    }
  } catch (error) {
    console.error('获取专辑播放列表失败:', error);
    // 失败时使用通用播放列表
    await fetchGenericPlaylist();
  }
}

// 获取通用播放列表
async function fetchGenericPlaylist() {
  try {
    const result = await get<{ list: AudioItem[] }>('/player/audio/list', {
      page: 1,
      pageSize: 100,
    });

    const index = result.list.findIndex(item => item._id === audioId.value);
    if (index >= 0) {
      audioStore.setPlaylist(result.list, index, true);
    }
  } catch (error) {
    console.error('获取播放列表失败:', error);
  }
}

// 格式化时长
function formatDuration(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, '0')}`;
}

/**
 * 获取分享卡片数据（从后端）
 */
async function fetchShareCard() {
  if (!audio.value?._id) return;
  try {
    const res = await get<ShareCardData>(`/share/card/${audio.value._id}`);
    shareData.value = res;
  } catch (e) {
    console.error('获取分享卡片失败', e);
  }
}

/**
 * 处理分享（增强版）
 */
async function handleShare() {
  trackEvent(AnalyticsEvents.SHARE_CLICK, { audioId: audio.value?._id });

  // 先获取最新的分享卡片数据
  await fetchShareCard();

  const shareTitle = shareData.value?.title || '声工坊有声作品';
  const shareDesc = shareData.value?.description || '用AI生成的高品质有声书，快来听！';
  const shareUrl = shareData.value?.shareUrl || copyShareLink();

  // #ifdef H5
  if (navigator.share) {
    try {
      await navigator.share({
        title: shareTitle,
        text: shareDesc,
        url: shareUrl,
      });
      await trackShareComplete('h5_share_api');
    } catch (e) {
      // 用户取消分享
      if ((e as Error).name !== 'AbortError') {
        await copyToClipboard(shareUrl);
      }
    }
    return;
  }
  // #endif

  // 小程序/App：复制链接
  await copyToClipboard(shareUrl);
}

/**
 * 向后端上报分享完成
 */
async function trackShareComplete(platform: string) {
  try {
    await post('/share/track', {
      audioId: audio.value?._id,
      platform,
      shareCode: shareData.value?.shareCode,
    });
    trackEvent(AnalyticsEvents.SHARE_COMPLETE, {
      audioId: audio.value?._id,
      platform,
    });
  } catch (e) {
    // 静默失败
  }
}

/**
 * 复制到剪贴板（带分享码链接）
 */
async function copyToClipboard(url: string) {
  try {
    await uni.setClipboardData({ data: url });
    uni.showToast({ title: '链接已复制，分享给朋友吧！', icon: 'success' });
    await trackShareComplete('copy_link');
  } catch (e) {
    uni.showToast({ title: '请截图分享', icon: 'none' });
  }
}

// 页面加载时，检测分享码来源
onLoad((options: any) => {
  const shareCode = options?.sc;
  if (shareCode) {
    // 上报分享访问
    get(`/share/visit?code=${shareCode}`).catch(() => {});
    trackEvent(AnalyticsEvents.INVITE_ACCEPT, { shareCode });
    // 存储分享码，用于后续注册绑定
    uni.setStorageSync('invite_code', shareCode);
  }
});

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

// 跳转进度
function handleSeek(e: any) {
  audioStore.seek(e.detail.value);
}

// 切换播放/暂停
function togglePlay() {
  audioStore.togglePlay();
}

// 播放模式
function togglePlayMode() {
  audioStore.togglePlayMode();
}

function getPlayModeIcon() {
  const icons = {
    sequence: '🔂',
    loop: '🔁',
    single: '🔂',
    random: '🔀',
  };
  return icons[audioStore.playMode] || '🔂';
}

function getPlayModeText() {
  const texts = {
    sequence: '顺序',
    loop: '循环',
    single: '单曲',
    random: '随机',
  };
  return texts[audioStore.playMode] || '顺序';
}

// 上一首
function playPrev() {
  if (hasPrev.value) {
    audioStore.playPrev();
    audio.value = audioStore.currentAudio;
  }
}

// 下一首
function playNext() {
  if (hasNext.value) {
    audioStore.playNext();
    audio.value = audioStore.currentAudio;
  }
}

// 从播放列表选择
function playFromPlaylist(index: number) {
  audioStore.play(playlist.value[index]);
  audio.value = playlist.value[index];
}

// 设置播放速度
function handleSetRate(rate: number) {
  audioStore.setPlayRate(rate);
  showRatePicker.value = false;
}

// 睡眠定时格式化
function formatSleepTimer(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${mins}:${secs.toString().padStart(2, '0')}`;
}

// 设置睡眠定时
function handleSetSleepTimer(seconds: number) {
  showSleepTimerPicker.value = false;

  if (seconds === -1) {
    // 当前播放结束
    const remaining = duration.value - currentTime.value;
    if (remaining > 0) {
      startSleepTimer(Math.ceil(remaining));
    } else {
      uni.showToast({ title: '当前播放即将结束', icon: 'none' });
      return;
    }
  } else {
    startSleepTimer(seconds);
  }
}

// 开始睡眠定时
function startSleepTimer(seconds: number) {
  // 清除之前的定时器
  if (sleepTimerInterval) {
    clearInterval(sleepTimerInterval);
  }

  sleepTimer.value = { remaining: seconds, total: seconds };
  sleepTimerInterval = setInterval(() => {
    if (sleepTimer.value) {
      sleepTimer.value.remaining--;
      if (sleepTimer.value.remaining <= 0) {
        clearInterval(sleepTimerInterval!);
        sleepTimerInterval = null;
        // 暂停播放（currentTime已保存，下次打开可继续）
        audioStore.pause();
        sleepTimer.value = null;
        uni.showToast({ title: '睡眠定时已到，自动暂停', icon: 'none' });
      }
    }
  }, 1000);
}

// 取消睡眠定时
function cancelSleepTimer() {
  showSleepTimerPicker.value = false;
  if (sleepTimerInterval) {
    clearInterval(sleepTimerInterval);
    sleepTimerInterval = null;
  }
  sleepTimer.value = null;
  uni.showToast({ title: '已取消睡眠定时', icon: 'none' });
}

// 切换收藏
async function toggleFavorite() {
  if (!audio.value) return;

  try {
    const result = await put<{ isFavorite: boolean }>(`/audio/${audio.value._id}/favorite`);
    audio.value.isFavorite = result.isFavorite;
    uni.showToast({
      title: result.isFavorite ? '已收藏' : '已取消收藏',
      icon: 'success',
    });
  } catch (error) {
    console.error('操作失败:', error);
  }
}

/**
 * 复制分享链接（旧版本兼容）
 */
function copyShareLink(): string {
  if (!audio.value) return '';

  // #ifdef H5
  const shareUrl = `${window.location.origin}/#/pages/player/index?id=${audio.value._id}`;
  // #endif

  // #ifndef H5
  // App 端使用 pages.json 中配置的原生分享或直接显示页面路径
  const shareUrl = `pages/player/index?id=${audio.value._id}`;
  // #endif

  return shareUrl;
}
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: linear-gradient(180deg, #1f2937 0%, #111827 100%);
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}

/* 空状态 */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 200rpx 40rpx;
  text-align: center;
}

.empty-icon {
  font-size: 120rpx;
  margin-bottom: 32rpx;
  opacity: 0.5;
}

.empty-title {
  font-size: 36rpx;
  font-weight: 600;
  color: #ffffff;
  margin-bottom: 16rpx;
}

.empty-desc {
  font-size: 28rpx;
  color: #9ca3af;
  margin-bottom: 48rpx;
}

.empty-btn {
  padding: 24rpx 64rpx;
  background: linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%);
  color: #ffffff;
  border-radius: 48rpx;
  font-size: 28rpx;
  border: none;
}

.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 44rpx 32rpx 24rpx;
}

.nav-center {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.nav-btn {
  width: 64rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease;
}

.nav-btn:active {
  transform: scale(0.85);
}

.sleep-timer-badge {
  display: flex;
  align-items: center;
  background: rgba(79, 70, 229, 0.3);
  padding: 8rpx 16rpx;
  border-radius: 24rpx;
  margin-top: 8rpx;
}

.sleep-timer-icon {
  font-size: 20rpx;
  margin-right: 6rpx;
}

.sleep-timer-text {
  font-size: 22rpx;
  color: #a5b4fc;
  font-weight: 500;
}

.nav-icon {
  font-size: 36rpx;
  color: #ffffff;
}

.nav-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #ffffff;
}

.cover-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 48rpx 0;
}

.cover {
  width: 320rpx;
  height: 320rpx;
  background: linear-gradient(135deg, #4f46e5 0%, #818cf8 100%);
  border-radius: 32rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 32rpx;
  box-shadow: 0 16rpx 48rpx rgba(79, 70, 229, 0.4);
}

.cover-icon {
  font-size: 96rpx;
}

.title {
  font-size: 36rpx;
  font-weight: 600;
  color: #ffffff;
  text-align: center;
  margin-bottom: 12rpx;
  max-width: 600rpx;
}

.meta {
  font-size: 24rpx;
  color: #9ca3af;
}

.text-preview {
  margin: 0 32rpx;
  padding: 24rpx;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 16rpx;
  width: calc(100% - 64rpx);
  box-sizing: border-box;
}

.lyrics-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  box-sizing: border-box;
}

.lyric-line {
  padding: 12rpx 16rpx;
  border-radius: 12rpx;
  opacity: 0.5;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 16rpx;
}

.lyric-line.active {
  background: rgba(79, 70, 229, 0.2);
  opacity: 1;
}

.lyric-text {
  font-size: 28rpx;
  color: #d1d5db;
  line-height: 1.8;
  white-space: pre-wrap;
  word-break: break-word;
  width: 100%;
  box-sizing: border-box;
}

.lyric-line.active .lyric-text {
  color: #ffffff;
  font-weight: 500;
}

.progress-section {
  display: flex;
  align-items: center;
  padding: 32rpx;
}

.time {
  font-size: 22rpx;
  color: #9ca3af;
  width: 80rpx;
  text-align: center;
}

.progress-slider {
  flex: 1;
  margin: 0 16rpx;
}

.controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24rpx 32rpx;
}

.controls-side,
.controls-center {
  display: flex;
  align-items: center;
}

.controls-side {
  margin-right: 16rpx;
}

.controls-center {
  margin-right: 24rpx;
}

.control-btn {
  width: 70rpx;
  height: 70rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
}

.control-btn.disabled {
  opacity: 0.4;
}

.control-btn.share-btn {
  flex-direction: column;
  width: 100rpx;
  height: 80rpx;
  background: linear-gradient(135deg, rgba(79, 70, 229, 0.3) 0%, rgba(129, 140, 248, 0.3) 100%);
}

.share-label {
  font-size: 18rpx;
  color: #a5b4fc;
  margin-top: 4rpx;
}

.control-text {
  font-size: 24rpx;
  color: #ffffff;
  font-weight: 600;
}

.control-icon {
  font-size: 36rpx;
  color: #ffffff;
}

.play-btn {
  width: 110rpx;
  height: 110rpx;
  background: linear-gradient(135deg, #4f46e5 0%, #818cf8 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8rpx 24rpx rgba(79, 70, 229, 0.5);
  border: 4rpx solid rgba(255, 255, 255, 0.3);
}

.play-icon {
  font-size: 44rpx;
  color: #ffffff;
  margin-left: 6rpx;
}

.bottom-actions {
  display: flex;
  justify-content: center;
  padding: 48rpx;
}

.bottom-actions .action-btn {
  margin: 0 40rpx;
}

.action-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: transparent;
  border: none;
  padding: 0;
  border-radius: 50%;
  padding: 16rpx;
  background: rgba(255, 255, 255, 0.1);
}

.action-icon {
  font-size: 48rpx;
  margin-bottom: 8rpx;
}

.action-text {
  font-size: 24rpx;
  color: #9ca3af;
}

.rate-picker {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: flex-end;
  z-index: 1000;
}

.rate-content {
  width: 100%;
  background: #1f2937;
  border-radius: 32rpx 32rpx 0 0;
  padding: 48rpx;
}

.rate-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #ffffff;
  text-align: center;
  margin-bottom: 32rpx;
}

.rate-options {
  display: flex;
  flex-wrap: wrap;
}

.rate-item {
  flex: 1;
  min-width: 180rpx;
  height: 80rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #374151;
  border-radius: 16rpx;
  border: 2rpx solid transparent;
  margin: 12rpx;
}

.rate-item.active {
  background: #4f46e5;
  border-color: #6366f1;
}

.rate-item text {
  font-size: 28rpx;
  color: #ffffff;
}

.sleep-timer-cancel {
  margin-top: 24rpx;
  padding: 24rpx;
  background: rgba(239, 68, 68, 0.2);
  border-radius: 16rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.sleep-timer-cancel text {
  font-size: 28rpx;
  color: #fca5a5;
}

/* 移动端播放列表设计 - 直接嵌入界面 */
.playlist-section-mobile {
  margin-top: 20rpx;
  background: rgba(31, 41, 55, 0.8); /* 半透明白色背景 */
  border-top-left-radius: 32rpx;
  border-top-right-radius: 32rpx;
  padding: 20rpx 0 0;
  box-shadow: 0 -8rpx 16rpx rgba(0, 0, 0, 0.1);
}

.playlist-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 32rpx 20rpx;
  border-bottom: 1rpx solid rgba(255, 255, 255, 0.1);
  margin-bottom: 16rpx;
}

.playlist-header-left {
  display: flex;
  align-items: center;
}

.playlist-header-left .playlist-mode-icon,
.playlist-header-left .playlist-count {
  margin-left: 16rpx;
}

.playlist-header-right {
  display: flex;
  align-items: center;
  padding: 12rpx 20rpx;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 40rpx;
}

.playlist-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #ffffff;
}

.playlist-count {
  font-size: 24rpx;
  color: #9ca3af;
}

.playlist-mode-icon {
  font-size: 28rpx;
}

.playlist-mode-text {
  font-size: 24rpx;
  color: #ffffff;
  font-weight: 500;
}

.playlist-list-mobile {
  padding: 0 16rpx 16rpx;
}

.playlist-item {
  display: flex;
  align-items: center;
  padding: 24rpx 32rpx;
  border-radius: 16rpx;
}

.playlist-item .playlist-info {
  margin-left: 20rpx;
}

.playlist-item .playing-icon {
  margin-left: auto;
}

.playlist-item.active {
  background: rgba(79, 70, 229, 0.2);
}

.playlist-index {
  width: 50rpx;
  height: 50rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.15); /* 更明显的背景 */
  border-radius: 50%;
  font-size: 24rpx;
  color: #ffffff; /* 白色文字 */
  flex-shrink: 0;
  font-weight: 600; /* 加粗 */
}

.playlist-item.active .playlist-index {
  background: #4f46e5;
  color: #ffffff;
}

.playlist-info {
  flex: 1;
  min-width: 0;
}

.playlist-item-title {
  font-size: 28rpx;
  color: #ffffff;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-bottom: 6rpx;
  font-weight: 500;
}

.playlist-item-meta {
  font-size: 24rpx;
  color: #9ca3af;
}

.playing-icon {
  width: 50rpx;
  height: 50rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24rpx;
  color: #4f46e5;
  background: rgba(79, 70, 229, 0.2); /* 背景使其更明显 */
  border-radius: 50%; /* 圆形背景 */
  flex-shrink: 0;
}
</style>