<script setup lang="ts">
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { openUrl } from "@tauri-apps/plugin-opener";
import pkg from "../package.json";

// --- 导航状态 ---
type Tab = 'clean-c-fast' | 'clean-c-advanced' | 'clean-c-deep' | 'clean-browser-chrome' | 'clean-browser-edge' | 'clean-memory';
const activeTab = ref<Tab>('clean-c-fast');
const isCMenuOpen = ref(true);
const isBrowserMenuOpen = ref(false);

// --- 数据结构 ---
interface ScanItem { name: string; path: string; size: number; count: number; enabled: boolean; }
interface FastScanResult { items: ScanItem[]; total_size: string; total_count: number; }
interface CleanResult { total_freed: string; success_count: number; fail_count: number; }
interface BrowserProfile { name: string; path_name: string; cache_size: number; cache_size_str: string; enabled: boolean; }
interface BrowserScanResult { profiles: BrowserProfile[]; total_size: string; }
interface FileNode {
  name: string; path: string; is_dir: boolean; size: number; size_str: string;
  percent: number; has_children: boolean;
  level: number; isOpen: boolean; isLoading: boolean;
}

// --- 状态管理 ---
const fastState = ref({
  isScanning: false,
  isCleaning: false,
  isDone: false,
  progress: 0,
  scanResult: null as FastScanResult | null,
  cleanResult: null as CleanResult | null,
});

const chromeState = ref({
  isScanning: false,
  isCleaning: false,
  isDone: false,
  scanResult: null as BrowserScanResult | null,
  cleanResult: null as CleanResult | null,
});

const edgeState = ref({
  isScanning: false,
  isCleaning: false,
  isDone: false,
  scanResult: null as BrowserScanResult | null,
  cleanResult: null as CleanResult | null,
});

const isFullScanning = ref(false);
const fullScanProgress = ref({ fileCount: 0, currentPath: "" });
const treeData = ref<FileNode[]>([]);

// --- 动态汇总计算 ---
import { computed } from "vue";

const selectedStats = computed(() => {
  const s = fastState.value;
  if (!s.scanResult) return { sizeStr: "0 B", count: 0, hasSelection: false };
  const enabledItems = s.scanResult.items.filter(i => i.enabled);
  const totalBytes = enabledItems.reduce((acc, i) => acc + i.size, 0);
  const totalCount = enabledItems.reduce((acc, i) => acc + i.count, 0);
  return {
    sizeStr: formatItemSize(totalBytes),
    count: totalCount,
    hasSelection: enabledItems.length > 0
  };
});

function getBrowserSelectedStats(state: any) {
  if (!state.scanResult) return { sizeStr: "0 B", count: 0, hasSelection: false };
  const enabledProfiles = state.scanResult.profiles.filter((p: any) => p.enabled);
  const totalBytes = enabledProfiles.reduce((acc: number, p: any) => acc + p.cache_size, 0);
  return {
    sizeStr: formatItemSize(totalBytes),
    count: enabledProfiles.length,
    hasSelection: enabledProfiles.length > 0
  };
}

const chromeSelectedStats = computed(() => getBrowserSelectedStats(chromeState.value));
const edgeSelectedStats = computed(() => getBrowserSelectedStats(edgeState.value));

// --- 弹窗状态 ---
const showModal = ref(false);
const modalTitle = ref("");
const modalMessage = ref("");
const modalType = ref<'info' | 'success' | 'error'>('info');

function showAlert(title: string, message: string, type: 'info' | 'success' | 'error' = 'info') {
  modalTitle.value = title;
  modalMessage.value = message;
  modalType.value = type;
  showModal.value = true;
}

// --- 右键菜单状态 ---
const contextMenu = ref({
  show: false,
  x: 0,
  y: 0,
  node: null as FileNode | null
});

function handleContextMenu(e: MouseEvent, node: FileNode) {
  e.preventDefault();
  contextMenu.value = {
    show: true,
    x: e.clientX,
    y: e.clientY,
    node: node
  };
  // 监听一次性点击以关闭菜单
  const close = () => {
    contextMenu.value.show = false;
    window.removeEventListener('click', close);
  };
  window.addEventListener('click', close);
}

async function openNodeInExplorer() {
  if (contextMenu.value.node) {
    try {
      await invoke("open_in_explorer", { path: contextMenu.value.node.path });
    } catch (err) {
      console.error(err);
    }
  }
}

async function searchNode(type: 'google' | 'perplexity') {
  if (contextMenu.value.node) {
    const name = contextMenu.value.node.name;
    const query = encodeURIComponent(`Windows 文件或目录 ${name} 是做什么用的，我可以删除吗`);
    const url = type === 'google' 
      ? `https://www.google.com/search?q=${query}`
      : `https://www.perplexity.ai/?q=${query}`;
    try {
      await openUrl(url);
    } catch (err) {
      console.error(err);
    }
  }
}

// 高级模式特有
const expandedAdvanced = ref<string | null>(null);
const advLoading = ref<Record<string, boolean>>({});

// --- 快速模式逻辑 ---
async function startFastScan() {
  const s = fastState.value;
  s.isScanning = true;
  s.isDone = false;
  s.progress = 0;
  s.scanResult = null;
  const interval = setInterval(() => { if (s.progress < 95) s.progress += Math.floor(Math.random() * 5); }, 100);
  try {
    const result = await invoke<FastScanResult>("start_fast_scan");
    s.progress = 100;
    s.scanResult = result;
  } catch (err) {
    showAlert("扫描失败", "请尝试以管理员身份运行程序。", 'error');
  } finally {
    clearInterval(interval);
    s.isScanning = false;
  }
}

async function startFastClean() {
  const s = fastState.value;
  if (s.isCleaning || !s.scanResult) return;
  const selectedPaths = s.scanResult.items
    .filter(item => item.enabled)
    .map(item => item.path);
  
  if (selectedPaths.length === 0) {
    showAlert("未选择任何项", "请至少勾选一个需要清理的项目。", 'info');
    return;
  }

  s.isCleaning = true;
  try {
    const res = await invoke<CleanResult>("start_fast_clean", { selectedPaths });
    s.cleanResult = res;
    s.isDone = true;
    s.scanResult = null;
  } catch (err) {
    showAlert("清理失败", String(err), 'error');
  } finally { s.isCleaning = false; }
}

// --- 高级模式逻辑 ---
async function runAdvancedTask(task: string) {
  advLoading.value[task] = true;
  try {
    let cmd = "";
    let title = "";
    if (task === 'dism') { cmd = "clean_system_components"; title = "系统组件清理"; }
    else if (task === 'thumb') { cmd = "clean_thumbnails"; title = "缩略图清理"; }
    else if (task === 'hiber') { cmd = "disable_hibernation"; title = "休眠文件优化"; }
    
    const res = await invoke<string>(cmd);
    showAlert(title, res, 'success');
  } catch (err) {
    showAlert("任务失败", String(err), 'error');
  } finally {
    advLoading.value[task] = false;
  }
}

// --- 浏览器清理逻辑 ---
async function startBrowserScan(browser: 'chrome' | 'edge') {
  const s = browser === 'chrome' ? chromeState.value : edgeState.value;
  s.isScanning = true;
  s.isDone = false;
  s.scanResult = null;
  s.cleanResult = null;
  try {
    const res = await invoke<BrowserScanResult>("start_browser_scan", { browser });
    s.scanResult = {
      ...res,
      profiles: res.profiles.map(p => ({ ...p, enabled: true }))
    };
  } catch (err) {
    showAlert("扫描失败", String(err), 'error');
  } finally {
    s.isScanning = false;
  }
}

async function startBrowserClean(browser: 'chrome' | 'edge') {
  const s = browser === 'chrome' ? chromeState.value : edgeState.value;
  if (!s.scanResult || s.isCleaning) return;
  const selectedProfiles = s.scanResult.profiles
    .filter(p => p.enabled)
    .map(p => p.path_name);
  
  if (selectedProfiles.length === 0) {
    showAlert("未选择", "请选择至少一个用户资料进行清理。", 'info');
    return;
  }

  s.isCleaning = true;
  try {
    const res = await invoke<CleanResult>("start_browser_clean", { browser, profiles: selectedProfiles });
    s.cleanResult = res;
    s.isDone = true;
    s.scanResult = null;
  } catch (err) {
    showAlert("清理失败", String(err), 'error');
  } finally {
    s.isCleaning = false;
  }
}

// --- 深度分析 (TreeSize) 逻辑 ---
async function startFullDiskScan() {
  isFullScanning.value = true;
  treeData.value = [];
  fullScanProgress.value = { fileCount: 0, currentPath: "" };
  
  // 监听进度
  const unlisten = await listen<{file_count: number, current_path: string}>("scan-progress", (event) => {
    fullScanProgress.value.fileCount = event.payload.file_count;
    fullScanProgress.value.currentPath = event.payload.current_path;
  });

  try {
    await invoke("start_full_disk_scan");
    const rootChildren = await invoke<FileNode[]>("get_tree_children", { path: "C:\\" });
    treeData.value = rootChildren.map(node => ({ ...node, level: 0, isOpen: false, isLoading: false }));
  } catch (err) {
    alert("扫描失败，请确保以管理员身份运行。");
  } finally {
    isFullScanning.value = false;
    unlisten();
  }
}

async function toggleNode(index: number) {
  const node = treeData.value[index];
  if (!node.is_dir || node.isLoading) return;
  if (node.isOpen) {
    let removeCount = 0;
    for (let i = index + 1; i < treeData.value.length; i++) {
      if (treeData.value[i].level > node.level) removeCount++;
      else break;
    }
    treeData.value.splice(index + 1, removeCount);
    node.isOpen = false;
  } else {
    node.isLoading = true;
    try {
      const children = await invoke<FileNode[]>("get_tree_children", { path: node.path });
      const mapped = children.map(c => ({ ...c, level: node.level + 1, isOpen: false, isLoading: false }));
      treeData.value.splice(index + 1, 0, ...mapped);
      node.isOpen = true;
    } catch (err) {
      console.error(err);
    } finally { node.isLoading = false; }
  }
}

function resetPageState() {
  if (activeTab.value === 'clean-c-fast') {
    fastState.value = { isScanning: false, isCleaning: false, isDone: false, progress: 0, scanResult: null, cleanResult: null };
  } else if (activeTab.value === 'clean-browser-chrome') {
    chromeState.value = { isScanning: false, isCleaning: false, isDone: false, scanResult: null, cleanResult: null };
  } else if (activeTab.value === 'clean-browser-edge') {
    edgeState.value = { isScanning: false, isCleaning: false, isDone: false, scanResult: null, cleanResult: null };
  }
}

function formatItemSize(bytes: number): string {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function splitSize(sizeStr: string | number) {
  const str = String(sizeStr);
  const parts = str.split(' ');
  if (parts.length === 2) {
    return { value: parts[0], unit: parts[1] };
  }
  return { value: str, unit: '' };
}
</script>

<template>
  <div class="app-container">
    <!-- 侧边栏 -->
    <aside class="sidebar">
      <div class="sidebar-header">
        <h2 class="brand">Windows 清理工具</h2>
      </div>
      
      <nav class="sidebar-nav">
        <!-- 清理 C 盘组 -->
        <div class="nav-group">
          <div class="nav-item-header" @click="isCMenuOpen = !isCMenuOpen">
            <span class="icon">💾</span>
            <span class="label">清理 C 盘</span>
            <span class="arrow" :class="{ open: isCMenuOpen }">▾</span>
          </div>
          <div class="nav-sub-items" v-show="isCMenuOpen">
            <div 
              class="nav-sub-item" 
              :class="{ active: activeTab === 'clean-c-fast' }"
              @click="activeTab = 'clean-c-fast'"
            >
              快速模式
            </div>
            <div 
              class="nav-sub-item" 
              :class="{ active: activeTab === 'clean-c-advanced' }"
              @click="activeTab = 'clean-c-advanced'"
            >
              高级模式
            </div>
            <div 
              class="nav-sub-item" 
              :class="{ active: activeTab === 'clean-c-deep' }"
              @click="activeTab = 'clean-c-deep'"
            >
              深度分析
            </div>
          </div>
        </div>

        <!-- 清理浏览器组 -->
        <div class="nav-group">
          <div class="nav-item-header" @click="isBrowserMenuOpen = !isBrowserMenuOpen">
            <span class="icon">🌐</span>
            <span class="label">清理浏览器</span>
            <span class="arrow" :class="{ open: isBrowserMenuOpen }">▾</span>
          </div>
          <div class="nav-sub-items" v-show="isBrowserMenuOpen">
            <div 
              class="nav-sub-item" 
              :class="{ active: activeTab === 'clean-browser-chrome' }"
              @click="activeTab = 'clean-browser-chrome'"
            >
              谷歌浏览器
            </div>
            <div 
              class="nav-sub-item" 
              :class="{ active: activeTab === 'clean-browser-edge' }"
              @click="activeTab = 'clean-browser-edge'"
            >
              微软浏览器
            </div>
          </div>
        </div>

        <!-- 其它项 -->
        <div 
          class="nav-item" 
          :class="{ active: activeTab === 'clean-memory' }"
          @click="activeTab = 'clean-memory'"
        >
          <span class="icon">🚀</span>
          <span class="label">清理内存</span>
        </div>
      </nav>
      
      <div class="sidebar-footer">
        <span class="version">v{{ pkg.version }}</span>
      </div>
    </aside>

    <!-- 内容区 -->
    <main class="content">
      <!-- 1. 快速清理页面 -->
      <section v-if="activeTab === 'clean-c-fast'" class="page-container">
        <div class="page-header">
          <div class="header-info">
            <h1>快速清理系统盘</h1>
            <p>一键释放 C 盘空间，不影响系统运行。</p>
          </div>
        </div>

        <div class="main-action">
          <!-- 扫描前/中 -->
          <div class="scan-circle-container" v-if="!fastState.scanResult && !fastState.isDone">
            <div class="scan-circle" :class="{ scanning: fastState.isScanning }">
              <div class="scan-inner" @click="!fastState.isScanning && startFastScan()">
                <span v-if="!fastState.isScanning" class="scan-btn-text">开始扫描</span>
                <span v-else class="scan-percent">{{ fastState.progress }}%</span>
              </div>
            </div>
          </div>

          <!-- 扫描完成 -->
          <div class="result-card" v-else-if="fastState.scanResult && !fastState.isDone">
            <div class="result-header">
              <span class="result-icon">📋</span>
              <h2>扫描完成</h2>
            </div>
            <div class="result-stats">
              <div class="stat-item">
                <span class="stat-value">
                  {{ splitSize(selectedStats.sizeStr).value }}
                  <span class="unit">{{ splitSize(selectedStats.sizeStr).unit }}</span>
                </span>
                <span class="stat-label">预计释放</span>
              </div>
              <div class="stat-divider"></div>
              <div class="stat-item">
                <span class="stat-value">{{ selectedStats.count }}</span>
                <span class="stat-label">文件数量</span>
              </div>
            </div>

            <button 
              class="btn-primary main-btn" 
              @click="startFastClean" 
              :disabled="fastState.isCleaning || !selectedStats.hasSelection"
            >
              {{ fastState.isCleaning ? '正在清理...' : '立即清理' }}
            </button>
          </div>

          <!-- 清理完成报告 -->
          <div class="result-card done-card" v-else-if="fastState.isDone && fastState.cleanResult">
            <div class="result-header">
              <span class="result-icon success">🎉</span>
              <h2>清理完成</h2>
            </div>
            
            <div class="result-stats">
              <div class="stat-item">
                <span class="stat-value">
                  {{ splitSize(fastState.cleanResult.total_freed).value }}
                  <span class="unit">{{ splitSize(fastState.cleanResult.total_freed).unit }}</span>
                </span>
                <span class="stat-label">释放空间</span>
              </div>
              <div class="stat-divider"></div>
              <div class="stat-item">
                <span class="stat-value">{{ fastState.cleanResult.success_count }}</span>
                <span class="stat-label">成功清理</span>
              </div>
              <div class="stat-divider"></div>
              <div class="stat-item">
                <span class="stat-value highlight-gray">{{ fastState.cleanResult.fail_count }}</span>
                <span class="stat-label">跳过/失败</span>
              </div>
            </div>
            <button class="btn-secondary" @click="resetPageState">返回</button>
          </div>
        </div>

        <div class="detail-list" v-if="(fastState.isScanning || fastState.scanResult) && !fastState.isDone">
          <h3>清理项详情</h3>
          <div 
            class="detail-item" 
            v-for="item in fastState.scanResult?.items || []" 
            :key="item.path"
            @click="item.enabled = !item.enabled"
            :class="{ disabled: !item.enabled }"
          >
            <div class="item-info">
              <label class="checkbox-container" @click.stop>
                <input type="checkbox" v-model="item.enabled">
                <span class="checkmark"></span>
              </label>
              <span>{{ item.name }}</span>
            </div>
            <span class="item-size">{{ formatItemSize(item.size) }}</span>
          </div>
          <div v-if="fastState.isScanning" class="scanning-placeholder">正在深度扫描文件系统...</div>
        </div>
      </section>

      <!-- 2. 高级模式页面 -->
      <section v-else-if="activeTab === 'clean-c-advanced'" class="page-container">
        <div class="page-header">
          <div class="header-info">
            <h1>高级清理工具</h1>
            <p>执行深层系统优化，释放更多磁盘空间。</p>
          </div>
        </div>

        <div class="adv-card-list">
          <!-- 系统组件 -->
          <div class="adv-card" :class="{ expanded: expandedAdvanced === 'dism' }">
            <div class="adv-card-main" @click="expandedAdvanced = expandedAdvanced === 'dism' ? null : 'dism'">
              <div class="adv-card-info">
                <span class="adv-card-icon">⚙️</span>
                <div class="adv-card-text">
                  <h3>系统组件清理</h3>
                  <p>通过 DISM 命令移除不再需要的系统冗余组件。</p>
                </div>
              </div>
              <button class="btn-action" @click.stop="runAdvancedTask('dism')" :disabled="advLoading['dism']">
                {{ advLoading['dism'] ? '执行中...' : '执行' }}
              </button>
            </div>
            <div class="adv-card-detail" v-show="expandedAdvanced === 'dism'">
              <div class="detail-content">
                <h4>详细信息：</h4>
                <p>Windows 在更新后会保留旧版本的组件。此操作会调用系统底层的 DISM 工具（StartComponentCleanup）进行物理移除。</p>
                <h4 class="warning-title">注意事项：</h4>
                <ul>
                  <li>执行后将无法卸载已安装的 Windows 更新。</li>
                  <li>过程可能较慢（需 1-5 分钟），请勿中途关闭程序。</li>
                  <li>需要管理员权限执行。</li>
                </ul>
              </div>
            </div>
          </div>

          <!-- 缩略图 -->
          <div class="adv-card" :class="{ expanded: expandedAdvanced === 'thumb' }">
            <div class="adv-card-main" @click="expandedAdvanced = expandedAdvanced === 'thumb' ? null : 'thumb'">
              <div class="adv-card-info">
                <span class="adv-card-icon">🖼️</span>
                <div class="adv-card-text">
                  <h3>清理缩略图缓存</h3>
                  <p>重置文件夹预览缩略图数据库以释放空间。</p>
                </div>
              </div>
              <button class="btn-action" @click.stop="runAdvancedTask('thumb')" :disabled="advLoading['thumb']">执行</button>
            </div>
            <div class="adv-card-detail" v-show="expandedAdvanced === 'thumb'">
              <div class="detail-content">
                <h4>详细信息：</h4>
                <p>系统会自动生成图片和视频的缩略图缓存（thumbcache_*.db）。当缓存过大或出现显示错误时，建议清理。</p>
                <h4 class="warning-title">注意事项：</h4>
                <ul>
                  <li>清理后，再次打开图片文件夹时加载预览会稍慢。</li>
                  <li>部分文件正被资源管理器使用时可能无法彻底删除。</li>
                </ul>
              </div>
            </div>
          </div>

          <!-- 休眠 -->
          <div class="adv-card" :class="{ expanded: expandedAdvanced === 'hiber' }">
            <div class="adv-card-main" @click="expandedAdvanced = expandedAdvanced === 'hiber' ? null : 'hiber'">
              <div class="adv-card-info">
                <span class="adv-card-icon">🌙</span>
                <div class="adv-card-text">
                  <h3>关闭休眠文件</h3>
                  <p>永久删除 hiberfil.sys 文件（大小等同于内存）。</p>
                </div>
              </div>
              <button class="btn-action" @click.stop="runAdvancedTask('hiber')" :disabled="advLoading['hiber']">执行</button>
            </div>
            <div class="adv-card-detail" v-show="expandedAdvanced === 'hiber'">
              <div class="detail-content">
                <h4>详细信息：</h4>
                <p>休眠文件（hiberfil.sys）占用大量 C 盘空间。对于使用 SSD且不常用休眠功能的用户，关闭它可以释放巨额空间。</p>
                <h4 class="warning-title">注意事项：</h4>
                <ul>
                  <li>关闭后将无法使用“休眠”功能及“快速启动”技术。</li>
                  <li>需要管理员权限。</li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </section>

      <!-- 2.5 浏览器清理页面 -->
      <section v-else-if="activeTab === 'clean-browser-chrome' || activeTab === 'clean-browser-edge'" class="page-container">
        <div class="page-header">
          <div class="header-info">
            <h1>清理{{ activeTab === 'clean-browser-chrome' ? '谷歌浏览器' : '微软浏览器' }}</h1>
            <p>安全清理浏览器缓存、临时文件，释放磁盘空间。</p>
          </div>
        </div>

        <div class="main-action">
          <!-- 谷歌浏览器视图 -->
          <template v-if="activeTab === 'clean-browser-chrome'">
            <!-- 扫描前 -->
            <div class="scan-circle-container" v-if="!chromeState.scanResult && !chromeState.isDone">
              <div class="scan-circle" :class="{ scanning: chromeState.isScanning }">
                <div class="scan-inner" @click="!chromeState.isScanning && startBrowserScan('chrome')">
                  <span v-if="!chromeState.isScanning" class="scan-btn-text">开始扫描</span>
                  <span v-else class="spinner"></span>
                </div>
              </div>
            </div>
            <!-- 扫描完成 -->
            <div class="result-card" v-else-if="chromeState.scanResult && !chromeState.isDone">
              <div class="result-header">
                <span class="result-icon">🌐</span>
                <h2>扫描完成</h2>
              </div>
              <div class="result-stats">
                <div class="stat-item">
                  <span class="stat-value">
                    {{ splitSize(chromeSelectedStats.sizeStr).value }}
                    <span class="unit">{{ splitSize(chromeSelectedStats.sizeStr).unit }}</span>
                  </span>
                  <span class="stat-label">预计释放</span>
                </div>
                <div class="stat-divider"></div>
                <div class="stat-item">
                  <span class="stat-value">{{ chromeSelectedStats.count }}</span>
                  <span class="stat-label">用户资料数量</span>
                </div>
              </div>
              <button class="btn-primary main-btn" @click="startBrowserClean('chrome')" :disabled="chromeState.isCleaning || !chromeSelectedStats.hasSelection">
                {{ chromeState.isCleaning ? '正在清理...' : '立即清理' }}
              </button>
            </div>
            <!-- 清理完成 -->
            <div class="result-card done-card" v-else-if="chromeState.isDone && chromeState.cleanResult">
              <div class="result-header">
                <span class="result-icon success">🎉</span>
                <h2>清理完成</h2>
              </div>
              <div class="result-stats">
                <div class="stat-item">
                  <span class="stat-value">
                    {{ splitSize(chromeState.cleanResult.total_freed).value }}
                    <span class="unit">{{ splitSize(chromeState.cleanResult.total_freed).unit }}</span>
                  </span>
                  <span class="stat-label">释放空间</span>
                </div>
                <div class="stat-divider"></div>
                <div class="stat-item">
                  <span class="stat-value">{{ chromeState.cleanResult.success_count }}</span>
                  <span class="stat-label">成功清理</span>
                </div>
              </div>
              <button class="btn-secondary" @click="resetPageState">返回</button>
            </div>
          </template>

          <!-- 微软浏览器视图 -->
          <template v-else-if="activeTab === 'clean-browser-edge'">
            <div class="scan-circle-container" v-if="!edgeState.scanResult && !edgeState.isDone">
              <div class="scan-circle" :class="{ scanning: edgeState.isScanning }">
                <div class="scan-inner" @click="!edgeState.isScanning && startBrowserScan('edge')">
                  <span v-if="!edgeState.isScanning" class="scan-btn-text">开始扫描</span>
                  <span v-else class="spinner"></span>
                </div>
              </div>
            </div>
            <div class="result-card" v-else-if="edgeState.scanResult && !edgeState.isDone">
              <div class="result-header">
                <span class="result-icon">🌐</span>
                <h2>扫描完成</h2>
              </div>
              <div class="result-stats">
                <div class="stat-item">
                  <span class="stat-value">
                    {{ splitSize(edgeSelectedStats.sizeStr).value }}
                    <span class="unit">{{ splitSize(edgeSelectedStats.sizeStr).unit }}</span>
                  </span>
                  <span class="stat-label">预计释放</span>
                </div>
                <div class="stat-divider"></div>
                <div class="stat-item">
                  <span class="stat-value">{{ edgeSelectedStats.count }}</span>
                  <span class="stat-label">用户资料数量</span>
                </div>
              </div>
              <button class="btn-primary main-btn" @click="startBrowserClean('edge')" :disabled="edgeState.isCleaning || !edgeSelectedStats.hasSelection">
                {{ edgeState.isCleaning ? '正在清理...' : '立即清理' }}
              </button>
            </div>
            <div class="result-card done-card" v-else-if="edgeState.isDone && edgeState.cleanResult">
              <div class="result-header">
                <span class="result-icon success">🎉</span>
                <h2>清理完成</h2>
              </div>
              <div class="result-stats">
                <div class="stat-item">
                  <span class="stat-value">
                    {{ splitSize(edgeState.cleanResult.total_freed).value }}
                    <span class="unit">{{ splitSize(edgeState.cleanResult.total_freed).unit }}</span>
                  </span>
                  <span class="stat-label">释放空间</span>
                </div>
                <div class="stat-divider"></div>
                <div class="stat-item">
                  <span class="stat-value">{{ edgeState.cleanResult.success_count }}</span>
                  <span class="stat-label">成功清理</span>
                </div>
              </div>
              <button class="btn-secondary" @click="resetPageState">返回</button>
            </div>
          </template>
        </div>

        <!-- 详情列表 -->
        <div class="detail-list" v-if="activeTab === 'clean-browser-chrome' ? (chromeState.isScanning || chromeState.scanResult) && !chromeState.isDone : (edgeState.isScanning || edgeState.scanResult) && !edgeState.isDone">
          <h3>用户资料列表</h3>
          <div 
            class="detail-item" 
            v-for="profile in (activeTab === 'clean-browser-chrome' ? chromeState.scanResult?.profiles : edgeState.scanResult?.profiles) || []" 
            :key="profile.path_name"
            @click="profile.enabled = !profile.enabled"
            :class="{ disabled: !profile.enabled }"
          >
            <div class="item-info">
              <label class="checkbox-container" @click.stop>
                <input type="checkbox" v-model="profile.enabled">
                <span class="checkmark"></span>
              </label>
              <span>{{ profile.name }}</span>
            </div>
            <span class="item-size">{{ profile.cache_size_str }}</span>
          </div>
          <div v-if="activeTab === 'clean-browser-chrome' ? chromeState.isScanning : edgeState.isScanning" class="scanning-placeholder">正在定位并分析浏览器用户资料...</div>
        </div>
      </section>

      <!-- 3. 深度分析页面 -->
      <section v-else-if="activeTab === 'clean-c-deep'" class="page-container full-width">
        <div class="page-header">
          <div class="header-info">
            <h1>查找大目录</h1>
            <p>层级化查看 C 盘占用，锁定空间大户。</p>
          </div>
          <div class="header-actions">
            <button class="btn-primary btn-sm" @click="startFullDiskScan" :disabled="isFullScanning">
              {{ isFullScanning ? '正在扫描...' : '开始扫描' }}
            </button>
          </div>
        </div>

        <div class="tree-table-container shadow-card" v-if="treeData.length > 0 || isFullScanning">
          <div v-if="isFullScanning" class="scanning-overlay">
            <div class="spinner"></div>
            <div class="scanning-status">
              <p class="scanning-main-text">正在扫描全盘文件...</p>
              <div class="scanning-stats-row">
                <span class="stat-badge">已扫描：{{ fullScanProgress.fileCount.toLocaleString() }} 个文件</span>
              </div>
              <p class="scanning-current-path" v-if="fullScanProgress.currentPath">
                当前：{{ fullScanProgress.currentPath }}
              </p>
            </div>
          </div>

          <div v-else class="tree-content-wrapper">
            <div class="tree-header">
              <span class="col-name">文件/文件夹名称</span>
              <span class="col-size">大小</span>
              <span class="col-graph">相对于父目录占比</span>
            </div>
            <div class="tree-body">
              <div 
                v-for="(node, index) in treeData" 
                :key="node.path" 
                class="tree-row"
                :class="{ 'is-file': !node.is_dir }"
                :style="{ paddingLeft: (node.level * 20 + 16) + 'px' }"
                @contextmenu="handleContextMenu($event, node)"
              >
                <div class="col-name" @click="toggleNode(index)">
                  <span v-if="node.is_dir" class="node-toggle">
                    {{ node.isLoading ? '⌛' : (node.isOpen ? '▼' : '▶') }}
                  </span>
                  <span v-else class="node-icon">📄</span>
                  <span class="node-text">{{ node.name }}</span>
                </div>
                <div class="col-size">{{ node.size_str }}</div>
                <div class="col-graph">
                  <div class="mini-bar-bg">
                    <div class="mini-bar-fill" :style="{ width: node.percent + '%' }"></div>
                  </div>
                  <span class="percent-text">{{ Math.round(node.percent) }}%</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      <!-- 4. 其他占位 -->
      <section v-else class="placeholder-page">
        <div class="empty-state">
          <span class="empty-icon">🛠️</span>
          <h1>功能开发中</h1>
          <p>此模块正在逐步完善，敬请期待。</p>
        </div>
      </section>
    </main>

    <!-- 右键菜单 -->
    <div 
      v-if="contextMenu.show" 
      class="context-menu shadow-card" 
      :style="{ top: contextMenu.y + 'px', left: contextMenu.x + 'px' }"
      @click.stop
    >
      <div class="menu-item" @click="openNodeInExplorer">
        <span class="menu-icon">📂</span>
        <span>在文件夹中打开</span>
      </div>
      <div class="menu-divider"></div>
      <div class="menu-item" @click="searchNode('google')">
        <span class="menu-icon">🌐</span>
        <span>用 Google 搜索</span>
      </div>
      <div class="menu-item" @click="searchNode('perplexity')">
        <span class="menu-icon">🤖</span>
        <span>询问 Perplexity</span>
      </div>
    </div>

    <!-- 自定义弹窗 -->
    <div class="modal-overlay" v-if="showModal" @click.self="showModal = false">
      <div class="modal-card" :class="modalType">
        <div class="modal-header">
          <span class="modal-icon">
            <template v-if="modalType === 'success'">✅</template>
            <template v-else-if="modalType === 'error'">❌</template>
            <template v-else>ℹ️</template>
          </span>
          <h3>{{ modalTitle }}</h3>
        </div>
        <div class="modal-body">
          <p>{{ modalMessage }}</p>
        </div>
        <div class="modal-footer">
          <button class="btn-primary" @click="showModal = false">确定</button>
        </div>
      </div>
    </div>
  </div>
</template>

<style>
/* --- 全局基础样式修复 --- */
:root {
  --primary-color: #007AFF;
  --primary-hover: #0063CC;
  --bg-light: #FBFBFD;
  --sidebar-bg: #FFFFFF;
  --text-main: #1D1D1F;
  --text-sec: #86868B;
  --border-color: #E5E5E7;
  --card-shadow: 0 12px 30px rgba(0, 0, 0, 0.04);
  --btn-shadow: 0 4px 12px rgba(0, 122, 255, 0.25);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body { 
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif; 
  color: var(--text-main); 
  background-color: var(--bg-light); 
  height: 100vh; 
  overflow: hidden; 
  -webkit-font-smoothing: antialiased;
}

#app { height: 100%; }

.app-container { 
  display: flex; 
  height: 100%; 
}

/* --- 侧边栏优化 (清爽浅蓝重构) --- */
.sidebar { 
  width: 240px; 
  background-color: #F8FAFD;
  border-right: 1px solid #E9EFF6;
  display: flex; 
  flex-direction: column; 
  padding: 40px 0 20px; 
  z-index: 10;
}

.sidebar-header { padding: 0 28px 36px; }
.brand { font-size: 20px; font-weight: 700; color: var(--text-main); letter-spacing: -0.3px; }


.sidebar-nav { flex: 1; }

.nav-item, .nav-item-header { 
  padding: 12px 20px; 
  margin: 4px 12px;
  display: flex; 
  align-items: center; 
  cursor: pointer; 
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); 
  color: #4A5568; 
  font-size: 14px; 
  font-weight: 500; 
  border-radius: 12px;
}

.nav-item:hover, .nav-item-header:hover { 
  background-color: #EDF2F7; 
  color: #2D3748;
}

.nav-item.active { 
  background-color: #EBF4FF; 
  color: #04448a; 
  font-weight: 600; 
}

.icon { margin-right: 12px; font-size: 18px; width: 24px; text-align: center; }

.arrow { 
  margin-left: auto; 
  transition: transform 0.3s; 
  font-size: 10px; 
  color: #A0AEC0; 
}
.arrow.open { transform: rotate(180deg); color: #4A5568; }

.nav-sub-items { margin-bottom: 8px; }
.nav-sub-item { 
  padding: 10px 20px 10px 52px; 
  margin: 2px 12px;
  cursor: pointer; 
  font-size: 13px; 
  color: #718096; 
  transition: all 0.2s; 
  border-radius: 10px;
}

.nav-sub-item:hover { 
  background-color: #EDF2F7; 
  color: #2D3748; 
}
.nav-sub-item.active { 
  color: #007AFF; 
  font-weight: 600; 
  background-color: #EBF4FF; 
}

.sidebar-footer { 
  padding: 0px 20px; 
  text-align: center;
}
.version { 
  font-size: 12px; 
  color: #CBD5E0; 
  font-weight: 500; 
  letter-spacing: 0.2px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

/* --- 内容区 --- */
.content { 
  flex: 1; 
  padding: 40px 60px; 
  overflow-y: auto; 
  height: 100%;
}
/* 当处于全屏模式（深度分析）时，内容区本身不滚动，让内部树形滚动 */
.content:has(.page-container.full-width) {
  overflow-y: hidden;
  padding-bottom: 24px; /* 调小全屏模式下的底部留白 */
}

.page-container { max-width: 800px; margin: 0 auto; padding-bottom: 0px; transition: max-width 0.4s ease; }
.page-container.full-width { 
  max-width: 1400px; 
  height: calc(100vh - 64px); /* 相应调整高度计算 */
  display: flex; 
  flex-direction: column; 
}
.page-header { 
  display: flex; 
  align-items: flex-end; 
  justify-content: space-between; 
  margin-bottom: 16px; 
  padding-bottom: 16px; 
  border-bottom: 1px solid var(--border-color); 
  flex-shrink: 0; 
}
.header-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.page-header h1 { font-size: 22px; font-weight: 700; margin-bottom: 0; color: var(--text-main); line-height: 1.2; }
.page-header p { color: var(--text-sec); font-size: 13px; margin-bottom: 0; line-height: 1.2; }
.header-actions { display: flex; align-items: center; }

/* --- 按钮样式重构 --- */
.btn-primary { 
  background-color: var(--primary-color); 
  color: white; 
  border: none; 
  padding: 12px 40px; 
  border-radius: 12px; 
  font-size: 15px; 
  font-weight: 600; 
  cursor: pointer; 
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); 
  box-shadow: var(--btn-shadow);
  flex-shrink: 0;
}
.btn-sm { padding: 8px 24px; font-size: 14px; border-radius: 10px; }
.btn-primary:hover { background-color: var(--primary-hover); transform: translateY(-1.5px); box-shadow: 0 6px 16px rgba(0, 122, 255, 0.35); }
.btn-primary:active { transform: translateY(0); }
.btn-primary:disabled { background-color: #D1D1D6; box-shadow: none; cursor: not-allowed; transform: none; }

.btn-secondary { 
  background-color: white; 
  color: var(--text-main); 
  border: 1px solid var(--border-color); 
  padding: 10px 28px; 
  border-radius: 10px; 
  font-size: 14px; 
  font-weight: 600; 
  cursor: pointer; 
  transition: all 0.2s; 
}
.btn-secondary:hover { background-color: #F5F5F7; }

/* --- 扫描结果卡片 (重点优化) --- */
.main-action { margin: 24px 0; display: flex; justify-content: center; }

.result-card { 
  background: white; 
  border-radius: 24px; 
  padding: 32px 40px; 
  width: 100%; 
  box-shadow: var(--card-shadow); 
  text-align: center; 
  border: 1px solid rgba(0,0,0,0.02); 
}

.result-header { margin-bottom: 24px; }
.result-icon { font-size: 28px; display: block; margin-bottom: 8px; }
.result-header h2 { font-size: 20px; font-weight: 700; color: var(--text-main); }

.result-stats { 
  display: flex; 
  justify-content: center; 
  align-items: center; 
  margin-bottom: 32px; 
}

.stat-item { 
  flex: 1; 
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stat-value { 
  display: flex; 
  align-items: baseline;
  justify-content: center;
  font-size: 38px; 
  font-weight: 800; 
  color: var(--primary-color); 
  letter-spacing: -1.2px;
  line-height: 1;
  margin-bottom: 6px;
  white-space: nowrap;
}

.stat-value .unit {
  font-size: 14px;
  font-weight: 700;
  margin-left: 3px;
  letter-spacing: 0;
  opacity: 0.9;
}

.stat-label { font-size: 13px; color: var(--text-sec); font-weight: 500; }

.stat-divider { 
  width: 1px; 
  height: 40px; 
  background-color: #F2F2F7; 
  margin: 0 16px; 
  flex-shrink: 0;
}

.main-btn { width: 180px; }

/* --- 扫描中 UI --- */
.scan-circle-container { width: 200px; height: 200px; margin: 0 auto; }
.scan-circle { 
  width: 100%; height: 100%; border-radius: 50%; border: 2px solid #F2F2F7; 
  display: flex; align-items: center; justify-content: center; position: relative; 
}
.scan-circle.scanning { border-color: transparent; }
.scan-circle.scanning::before {
  content: "";
  position: absolute;
  top: -2px; left: -2px; right: -2px; bottom: -2px;
  border-radius: 50%;
  border: 3px solid var(--primary-color);
  border-top-color: transparent;
  animation: spin 1s linear infinite;
}
.scan-inner { 
  width: 168px; height: 168px; border-radius: 50%; background: white; 
  display: flex; align-items: center; justify-content: center; 
  cursor: pointer; box-shadow: 0 10px 25px rgba(0,0,0,0.05); transition: transform 0.2s ease; 
}
.scan-inner:hover { transform: scale(1.03); }
.scan-btn-text { font-size: 18px; font-weight: 700; color: var(--primary-color); }
.scan-percent { font-size: 36px; font-weight: 800; color: var(--primary-color); letter-spacing: -1px; }

.stat-value.highlight-gray { color: #8E8E93; }

.done-card { border: 2px solid #E8F5E9; }
.result-icon.success { color: #34C759; font-size: 48px; margin-bottom: 12px; display: block; }
.clean-summary { font-size: 18px; color: var(--text-main); font-weight: 700; margin-top: 10px; }

/* --- 高级模式卡片 --- */
.adv-card-list { display: flex; flex-direction: column; gap: 20px; }
.adv-card { 
  background: #fff; 
  border-radius: 20px; 
  box-shadow: var(--card-shadow); 
  border: 1px solid rgba(0,0,0,0.02); 
  overflow: hidden; 
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); 
}
.adv-card:hover { transform: translateY(-2px); box-shadow: 0 15px 35px rgba(0,0,0,0.06); }

.adv-card-main { 
  padding: 24px 32px; 
  display: flex; 
  align-items: center; 
  justify-content: space-between; 
  cursor: pointer; 
}
.adv-card-main:hover { background: #FAFAFA; }

.adv-card-info { display: flex; align-items: center; gap: 24px; }
.adv-card-icon { font-size: 32px; }
.adv-card-text h3 { font-size: 18px; margin-bottom: 4px; font-weight: 700; color: var(--text-main); }
.adv-card-text p { color: var(--text-sec); font-size: 14px; }

.btn-action { 
  background-color: #F2F2F7; 
  color: var(--primary-color); 
  border: none; 
  padding: 10px 24px; 
  border-radius: 10px; 
  font-weight: 700; 
  font-size: 14px;
  cursor: pointer; 
  transition: all 0.2s ease; 
  min-width: 90px;
}
.btn-action:hover { background-color: var(--primary-color); color: #fff; transform: scale(1.05); }
.btn-action:disabled { background-color: #E5E5E7; color: #A1A1A1; cursor: not-allowed; transform: none; }

.adv-card-detail { 
  padding: 0 32px 32px 88px; 
  border-top: 1px solid #F5F5F7; 
  background: #FCFCFD; 
}
.detail-content { padding-top: 24px; }
.detail-content h4 { font-size: 14px; margin-bottom: 10px; color: var(--text-main); font-weight: 700; }
.detail-content p { font-size: 14px; color: var(--text-sec); line-height: 1.6; margin-bottom: 16px; }
.warning-title { color: #FF9500 !important; margin-top: 20px; }
.detail-content ul { padding-left: 18px; color: var(--text-sec); font-size: 13px; }
.detail-content li { margin-bottom: 8px; line-height: 1.4; }

/* --- 磁盘树样式 --- */
/* .advanced-actions { display: flex; justify-content: center; margin-bottom: 32px; flex-shrink: 0; } */
.tree-table-container { 
  background: #fff; 
  border-radius: 24px; 
  overflow: hidden; 
  margin-top: 8px; 
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  box-shadow: var(--card-shadow); 
  border: 1px solid rgba(0,0,0,0.02); 
}
.tree-content-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.tree-header { 
  display: flex; 
  background: #F9FAFB; 
  padding: 16px 24px; 
  font-size: 12px; 
  font-weight: 700; 
  color: var(--text-sec); 
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 1px solid var(--border-color); 
  flex-shrink: 0;
}
.tree-body { 
  flex: 1;
  overflow-y: auto; 
}
.tree-row { 
  display: flex; 
  align-items: center; 
  padding: 14px 24px; 
  border-bottom: 1px solid #F5F5F7; 
  font-size: 14px; 
  transition: background 0.15s ease; 
}
.tree-row:hover { background: #F9F9FB; }
.tree-row.is-file { color: #424245; }

.col-name { 
  flex: 2; 
  display: flex; 
  align-items: center; 
  font-weight: 500;
  min-width: 0;
}
.node-text {
  white-space: nowrap; 
  overflow: hidden; 
  text-overflow: ellipsis;
  flex: 1;
}
.col-size { width: 100px; text-align: right; font-weight: 600; color: var(--text-main); flex-shrink: 0; }
.col-graph { width: 180px; display: flex; align-items: center; gap: 12px; padding-left: 32px; flex-shrink: 0; }

.mini-bar-bg { flex: 1; height: 6px; background: #F0F0F2; border-radius: 3px; overflow: hidden; }
.mini-bar-fill { 
  height: 100%; 
  background: linear-gradient(90deg, #007AFF, #5856D6); 
  border-radius: 3px; 
  transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.percent-text { font-size: 11px; color: var(--text-sec); width: 32px; font-weight: 600; text-align: right; }
.node-toggle { width: 24px; cursor: pointer; color: #C1C1C1; display: inline-block; text-align: center; font-size: 10px; transition: color 0.2s; }
.node-toggle:hover { color: var(--primary-color); }
.node-icon { width: 24px; font-size: 14px; opacity: 0.7; }

/* --- 通用状态 --- */
.scanning-loader, .scanning-overlay { padding: 100px 40px; text-align: center; color: var(--text-sec); }
.scanning-status { margin-top: 16px; }
.scanning-main-text { font-size: 16px; font-weight: 600; color: var(--text-main); margin-bottom: 12px; }
.scanning-stats-row { margin-bottom: 16px; }
.stat-badge { background: #EBF4FF; color: var(--primary-color); padding: 6px 16px; border-radius: 20px; font-size: 13px; font-weight: 700; }
.scanning-current-path { font-size: 12px; color: var(--text-sec); max-width: 500px; margin: 0 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; opacity: 0.8; }

.spinner { 
  width: 44px; height: 44px; 
  border: 3px solid #F2F2F7; 
  border-top: 3px solid var(--primary-color); 
  border-radius: 50%; 
  animation: spin 0.8s linear infinite; 
  margin: 0 auto 24px; 
}

.detail-list { 
  background: white; 
  border-radius: 20px; 
  padding: 32px; 
  box-shadow: var(--card-shadow); 
  margin-top: 40px; 
  border: 1px solid rgba(0,0,0,0.02); 
}
.detail-list h3 { font-size: 18px; margin-bottom: 20px; font-weight: 700; color: var(--text-main); }
.detail-item { 
  display: flex; 
  justify-content: space-between; 
  align-items: center;
  padding: 16px 0; 
  border-bottom: 1px solid #F5F5F7; 
  font-size: 14px; 
  color: #424245; 
  transition: all 0.2s ease;
  cursor: pointer;
}
.detail-item:hover { background-color: #FAFAFB; padding-left: 8px; padding-right: 8px; border-radius: 8px; }
.detail-item.disabled { opacity: 0.5; }
.detail-item:last-child { border-bottom: none; }

.item-info { display: flex; align-items: center; gap: 12px; }

/* --- 自定义复选框 --- */
.checkbox-container {
  display: block;
  position: relative;
  width: 20px;
  height: 20px;
  cursor: pointer;
  user-select: none;
}

.checkbox-container input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0; width: 0;
}

.checkmark {
  position: absolute;
  top: 0; left: 0;
  height: 20px; width: 20px;
  background-color: #F2F2F7;
  border-radius: 6px;
  transition: all 0.2s;
  border: 1px solid #E5E5E7;
}

.checkbox-container:hover input ~ .checkmark { background-color: #E5E5E7; }
.checkbox-container input:checked ~ .checkmark { background-color: var(--primary-color); border-color: var(--primary-color); }

.checkmark:after {
  content: "";
  position: absolute;
  display: none;
  left: 6px; top: 1px;
  width: 5px; height: 10px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.checkbox-container input:checked ~ .checkmark:after { display: block; }

.item-size { font-weight: 600; color: var(--primary-color); }

.placeholder-page { padding-top: 120px; text-align: center; color: var(--text-sec); }
.empty-icon { font-size: 64px; display: block; margin-bottom: 24px; opacity: 0.5; }

@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(0, 122, 255, 0.3); } 70% { box-shadow: 0 0 0 25px rgba(0, 122, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(0, 122, 255, 0); } }

/* --- 自定义弹窗样式 --- */
.modal-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  background-color: rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.2s ease;
}

.modal-card {
  background: white;
  width: 400px;
  border-radius: 24px;
  padding: 32px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.15);
  text-align: center;
  animation: modalIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.modal-header { margin-bottom: 20px; }
.modal-icon { font-size: 40px; display: block; margin-bottom: 12px; }
.modal-header h3 { font-size: 20px; font-weight: 700; color: var(--text-main); }

.modal-card.success .modal-header h3 { color: #34C759; }
.modal-card.error .modal-header h3 { color: #FF3B30; }

.modal-body { margin-bottom: 32px; }
.modal-body p { color: var(--text-sec); font-size: 15px; line-height: 1.6; }

.modal-footer { display: flex; justify-content: center; }

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn { from { opacity: 0; transform: scale(0.9) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }

/* --- 右键菜单样式 --- */
.context-menu {
  position: fixed;
  background: white;
  min-width: 180px;
  border-radius: 12px;
  padding: 6px;
  z-index: 2000;
  border: 1px solid rgba(0,0,0,0.08);
  animation: fadeIn 0.1s ease;
}

.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--text-main);
  cursor: pointer;
  border-radius: 8px;
  transition: background 0.15s;
}

.menu-item:hover {
  background-color: #F2F2F7;
  color: var(--primary-color);
}

.menu-icon { font-size: 16px; }

.menu-divider {
  height: 1px;
  background: #F5F5F7;
  margin: 4px 0;
}
</style>