import 'dart:async';
import 'dart:io';
import 'dart:ui';

import 'package:cross_file/cross_file.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:cloudreve4_flutter/data/models/file_model.dart';
import 'package:cloudreve4_flutter/services/file_service.dart';
import 'package:cloudreve4_flutter/services/upload_service.dart';
import '../../../core/utils/file_utils.dart';
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../providers/file_manager_provider.dart';
import '../../providers/download_manager_provider.dart';
import '../../providers/upload_manager_provider.dart';
import '../../providers/navigation_provider.dart';
import '../../widgets/file_list_item.dart';
import '../../widgets/file_grid_item.dart';
import '../../widgets/file_list_header.dart';
import '../../widgets/file_breadcrumb.dart';
import '../../widgets/selection_toolbar.dart';
import '../../widgets/empty_folder_view.dart';
import '../../widgets/upload_dialog.dart';
import '../../widgets/file_operation_dialogs.dart';
import '../../widgets/file_info_dialog.dart';
import '../../widgets/search_dialog.dart';
import '../../widgets/toast_helper.dart';
import '../../../router/app_router.dart';
import '../../../core/utils/file_type_utils.dart';

class FilesPage extends StatefulWidget {
  const FilesPage({super.key});

  @override
  State<FilesPage> createState() => _FilesPageState();
}

class _FilesPageState extends State<FilesPage> {
  bool _isFirstLoad = true;
  FileModel? _infoFile;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  // FAB 状态
  bool _isFabVisible = true;
  bool _isFabExpanded = false;
  Timer? _fabShowTimer;

  // 桌面端拖拽状态
  bool _isDraggingOver = false;

  @override
  void initState() {
    super.initState();

    Future.delayed(const Duration(milliseconds: 100), () {
      if (mounted) {
        final fileManager = Provider.of<FileManagerProvider>(context, listen: false);
        final screenWidth = MediaQuery.of(context).size.width;
        if (screenWidth >= 1000) {
          fileManager.setViewType(FileViewType.grid);
        } else {
          fileManager.setViewType(FileViewType.list);
        }
        if (_isFirstLoad) {
          fileManager.loadFiles();
          _isFirstLoad = false;
        }
        final downloadManager = Provider.of<DownloadManagerProvider>(context, listen: false);
        downloadManager.initialize();
      }
    });

    // 上传完成 → 自动刷新当前目录文件列表
    UploadService.instance.onUploadCompleted = (targetPath, fileName) {
      if (!mounted) return;
      final fileManager = Provider.of<FileManagerProvider>(context, listen: false);
      final normalizedCurrent = FileUtils.toCloudreveUri(fileManager.currentPath);
      if (targetPath == normalizedCurrent) {
        final fileUri = targetPath.endsWith('/')
            ? '$targetPath$fileName'
            : '$targetPath/$fileName';
        fileManager.addFileByUri(fileUri);
      }
    };
  }

  @override
  void dispose() {
    _fabShowTimer?.cancel();
    UploadService.instance.onUploadCompleted = null;
    super.dispose();
  }

  void _showFileInfo(FileModel file) {
    setState(() => _infoFile = file);
    // 等待下一帧 rebuild 完成，endDrawer 从 null 变为非 null 后再打开
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _scaffoldKey.currentState?.openEndDrawer();
    });
  }

  void _showSelectionMore(
    FileModel file,
    FileManagerProvider fileManager,
  ) {
    showModalBottomSheet<void>(
      context: context,
      builder: (sheetContext) => SafeArea(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            ListTile(
              leading: const Icon(Icons.edit),
              title: const Text('重命名'),
              onTap: () {
                Navigator.of(sheetContext).pop();
                FileOperationDialogs.showRenameDialog(context, fileManager, file);
              },
            ),
            ListTile(
              leading: const Icon(Icons.info_outline),
              title: const Text('查看详情'),
              onTap: () {
                Navigator.of(sheetContext).pop();
                _showFileInfo(file);
              },
            ),
          ],
        ),
      ),
    );
  }

  // ---- FAB 显隐控制 ----

  void _hideFab() {
    _fabShowTimer?.cancel();
    if (_isFabVisible) {
      setState(() {
        _isFabVisible = false;
        _isFabExpanded = false;
      });
    }
  }

  void _scheduleShowFab() {
    _fabShowTimer?.cancel();
    _fabShowTimer = Timer(const Duration(seconds: 1), () {
      if (mounted && !_isFabVisible) {
        setState(() => _isFabVisible = true);
      }
    });
  }

  bool _onScrollNotification(ScrollNotification notification) {
    if (notification is ScrollStartNotification ||
        notification is ScrollUpdateNotification) {
      _hideFab();
    } else if (notification is ScrollEndNotification) {
      _scheduleShowFab();
    }
    return false;
  }

  void _toggleFabExpanded() {
    setState(() => _isFabExpanded = !_isFabExpanded);
  }

  void _onFabSubAction(VoidCallback action) {
    setState(() => _isFabExpanded = false);
    action();
  }

  // ---- 构建方法 ----

  @override
  Widget build(BuildContext context) {
    final isDesktop = MediaQuery.of(context).size.width >= 1000;

    return Scaffold(
      key: _scaffoldKey,
      appBar: _buildAppBar(context),
      body: _buildBody(context),
      bottomNavigationBar: _buildBottomBar(context),
      endDrawer: _infoFile != null ? FileInfoPanel(file: _infoFile!) : null,
      floatingActionButton: isDesktop ? null : _buildSpeedDialFAB(context),
    );
  }

  PreferredSizeWidget _buildAppBar(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final isDesktop = screenWidth >= 1000;

    return AppBar(
      title: Consumer<FileManagerProvider>(
        builder: (context, fileManager, child) {
          if (isDesktop) {
            if (fileManager.currentPath == '/') {
              return const Text('文件');
            }
            return _buildDesktopBreadcrumb(context, fileManager);
          }
          return _buildMobileBreadcrumb(context, fileManager);
        },
      ),
      actions: isDesktop ? _buildDesktopActions() : _buildMobileActions(),
    );
  }

  /// 循环解码路径段，处理多重 URL 编码（如 %25E4%25B8%25AD → 中文）
  String _decodePathSegment(String segment) {
    var decoded = segment;
    for (var i = 0; i < 5; i++) {
      try {
        final next = Uri.decodeComponent(decoded);
        if (next == decoded) break;
        decoded = next;
      } catch (_) {
        break;
      }
    }
    return decoded;
  }

  Widget _buildDesktopBreadcrumb(BuildContext context, FileManagerProvider fileManager) {
    final theme = Theme.of(context);
    final colorScheme = theme.colorScheme;
    final pathParts = fileManager.currentPath.split('/');
    pathParts.removeWhere((part) => part.isEmpty);

    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        InkWell(
          onTap: () => fileManager.currentPath != '/' ? fileManager.enterFolder('/') : null,
          borderRadius: BorderRadius.circular(6),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
            child: Icon(LucideIcons.home, size: 18, color: colorScheme.primary),
          ),
        ),
        for (int i = 0; i < pathParts.length; i++) ...[
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 2),
            child: Icon(LucideIcons.chevronRight, size: 14, color: theme.hintColor.withValues(alpha: 0.5)),
          ),
          InkWell(
            onTap: () {
              final targetPath = '/${pathParts.sublist(0, i + 1).join('/')}';
              if (targetPath != fileManager.currentPath) fileManager.enterFolder(targetPath);
            },
            borderRadius: BorderRadius.circular(6),
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
              child: Text(
                _decodePathSegment(pathParts[i]),
                style: TextStyle(
                  color: i == pathParts.length - 1 ? colorScheme.onSurface : colorScheme.primary,
                  fontWeight: i == pathParts.length - 1 ? FontWeight.w600 : FontWeight.normal,
                ),
              ),
            ),
          ),
        ],
      ],
    );
  }

  Widget _buildMobileBreadcrumb(BuildContext context, FileManagerProvider fileManager) {
    final theme = Theme.of(context);
    final colorScheme = theme.colorScheme;
    final pathParts = fileManager.currentPath.split('/');
    pathParts.removeWhere((part) => part.isEmpty);

    return SizedBox(
      height: 40,
      child: ListView(
        key: const PageStorageKey('mobile_breadcrumb'),
        scrollDirection: Axis.horizontal,
        children: [
          _buildBreadcrumbChip(
            context,
            label: '文件',
            icon: LucideIcons.home,
            color: colorScheme.primary,
            onTap: () => fileManager.currentPath != '/' ? fileManager.enterFolder('/') : null,
          ),
          for (int i = 0; i < pathParts.length; i++) ...[
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 2),
              child: Icon(LucideIcons.chevronRight, size: 14, color: theme.hintColor.withValues(alpha: 0.5)),
            ),
            _buildBreadcrumbChip(
              context,
              label: _decodePathSegment(pathParts[i]),
              icon: null,
              color: colorScheme.primary,
              isLast: i == pathParts.length - 1,
              onTap: () {
                final targetPath = '/${pathParts.sublist(0, i + 1).join('/')}';
                if (targetPath != fileManager.currentPath) fileManager.enterFolder(targetPath);
              },
            ),
          ],
        ],
      ),
    );
  }

  Widget _buildBreadcrumbChip(
    BuildContext context, {
    required String label,
    required IconData? icon,
    required Color color,
    bool isLast = false,
    VoidCallback? onTap,
  }) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(14),
      child: Container(
        height: 28,
        padding: const EdgeInsets.symmetric(horizontal: 8),
        decoration: BoxDecoration(
          color: isLast ? color.withValues(alpha: 0.15) : color.withValues(alpha: 0.06),
          borderRadius: BorderRadius.circular(14),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            if (icon != null) ...[
              Icon(icon, size: 14, color: color),
              const SizedBox(width: 3),
            ],
            Text(
              label,
              style: TextStyle(
                color: color,
                fontWeight: isLast ? FontWeight.w600 : FontWeight.w500,
                fontSize: 12,
              ),
            ),
          ],
        ),
      ),
    );
  }

  List<Widget> _buildDesktopActions() {
    return [
      IconButton(
        icon: const Icon(LucideIcons.search),
        onPressed: () => SearchDialog.show(context),
        tooltip: '搜索',
      ),
      Consumer<FileManagerProvider>(
        builder: (context, fileManager, child) {
          return IconButton(
            icon: Icon(fileManager.isLoading ? Icons.hourglass_empty : Icons.refresh),
            onPressed: () => fileManager.refreshFiles(),
            tooltip: '刷新',
          );
        },
      ),
      Consumer<FileManagerProvider>(
        builder: (context, fileManager, child) {
          final icon = fileManager.viewType == FileViewType.list
              ? Icons.grid_view
              : Icons.view_list;
          return IconButton(
            icon: Icon(icon),
            onPressed: () {
              fileManager.setViewType(
                fileManager.viewType == FileViewType.list
                    ? FileViewType.grid
                    : FileViewType.list,
              );
            },
            tooltip: fileManager.viewType == FileViewType.list ? '网格视图' : '列表视图',
          );
        },
      ),
      IconButton(
        icon: const Icon(Icons.add),
        onPressed: () {
          final fileManager = Provider.of<FileManagerProvider>(context, listen: false);
          FileOperationDialogs.showCreateDialog(context, fileManager);
        },
        tooltip: '新建',
      ),
      IconButton(
        icon: const Icon(Icons.cloud_upload),
        onPressed: () => showUploadDialog(context),
        tooltip: '上传',
      ),
      IconButton(
        icon: const Icon(Icons.cloud_download),
        onPressed: () => Provider.of<NavigationProvider>(context, listen: false).setIndex(2),
        tooltip: '下载',
      ),
    ];
  }

  List<Widget> _buildMobileActions() {
    return [
      Consumer<FileManagerProvider>(
        builder: (context, fileManager, child) {
          final icon = fileManager.viewType == FileViewType.list
              ? Icons.grid_view
              : Icons.view_list;
          return IconButton(
            icon: Icon(icon),
            onPressed: () {
              fileManager.setViewType(
                fileManager.viewType == FileViewType.list
                    ? FileViewType.grid
                    : FileViewType.list,
              );
            },
            tooltip: fileManager.viewType == FileViewType.list ? '网格视图' : '列表视图',
          );
        },
      ),
    ];
  }

  // ---- SpeedDial FAB ----

  Widget _buildSpeedDialFAB(BuildContext context) {
    final theme = Theme.of(context);
    final colorScheme = theme.colorScheme;
    final isDark = theme.brightness == Brightness.dark;

    return AnimatedSlide(
      offset: _isFabVisible ? Offset.zero : const Offset(0, 2),
      duration: const Duration(milliseconds: 250),
      curve: Curves.easeInOut,
      child: AnimatedOpacity(
        opacity: _isFabVisible ? 1.0 : 0.0,
        duration: const Duration(milliseconds: 250),
        curve: Curves.easeInOut,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            _buildFabSubItem(
              context: context,
              index: 0,
              icon: LucideIcons.search,
              label: '搜索',
              isDark: isDark,
              colorScheme: colorScheme,
              onTap: () => _onFabSubAction(() => SearchDialog.show(context)),
            ),
            _buildFabSubItem(
              context: context,
              index: 1,
              icon: LucideIcons.upload,
              label: '上传',
              isDark: isDark,
              colorScheme: colorScheme,
              onTap: () => _onFabSubAction(() => showUploadDialog(context)),
            ),
            _buildFabSubItem(
              context: context,
              index: 2,
              icon: LucideIcons.folderPlus,
              label: '新建文件夹',
              isDark: isDark,
              colorScheme: colorScheme,
              onTap: () {
                final fileManager = Provider.of<FileManagerProvider>(context, listen: false);
                _onFabSubAction(() => FileOperationDialogs.showCreateDialog(context, fileManager));
              },
            ),
            _buildFabSubItem(
              context: context,
              index: 3,
              icon: LucideIcons.download,
              label: '离线下载',
              isDark: isDark,
              colorScheme: colorScheme,
              onTap: () => _onFabSubAction(() => Navigator.of(context).pushNamed(RouteNames.remoteDownload)),
            ),
            Consumer<FileManagerProvider>(
              builder: (context, fileManager, _) {
                final isListView = fileManager.viewType == FileViewType.list;
                return _buildFabSubItem(
                  context: context,
                  index: 4,
                  icon: isListView ? LucideIcons.layoutGrid : LucideIcons.list,
                  label: isListView ? '网格视图' : '列表视图',
                  isDark: isDark,
                  colorScheme: colorScheme,
                  onTap: () {
                    _onFabSubAction(() {
                      fileManager.setViewType(
                        isListView ? FileViewType.grid : FileViewType.list,
                      );
                    });
                  },
                );
              },
            ),

            // 主按钮：与子按钮同风格同尺寸
            Padding(
              padding: const EdgeInsets.only(bottom: 4, right: 4),
              child: AnimatedScale(
                scale: _isFabExpanded ? 1.0 : 1.08,
                duration: const Duration(milliseconds: 250),
                curve: Curves.easeInOut,
                child: _buildFabButton(
                  isDark: isDark,
                  colorScheme: colorScheme,
                  onTap: _toggleFabExpanded,
                  child: AnimatedRotation(
                    turns: _isFabExpanded ? 0.125 : 0,
                    duration: const Duration(milliseconds: 250),
                    curve: Curves.easeInOut,
                    child: Icon(
                      LucideIcons.plus,
                      color: colorScheme.primary,
                      size: 22,
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFabSubItem({
    required BuildContext context,
    required int index,
    required IconData icon,
    required String label,
    required bool isDark,
    required ColorScheme colorScheme,
    required VoidCallback onTap,
  }) {
    final staggerDelay = Duration(milliseconds: 50 * index);

    return AnimatedSlide(
      offset: _isFabExpanded ? Offset.zero : const Offset(0, 1.2),
      duration: const Duration(milliseconds: 250) + staggerDelay,
      curve: Curves.easeOutCubic,
      child: AnimatedOpacity(
        opacity: _isFabExpanded ? 1.0 : 0.0,
        duration: const Duration(milliseconds: 200) + staggerDelay,
        curve: Curves.easeOut,
        child: AnimatedScale(
          scale: _isFabExpanded ? 1.0 : 0.4,
          duration: const Duration(milliseconds: 250) + staggerDelay,
          curve: Curves.easeOutCubic,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 14, right: 4),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                ClipRRect(
                  borderRadius: BorderRadius.circular(10),
                  child: BackdropFilter(
                    filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
                    child: Container(
                      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 7),
                      decoration: BoxDecoration(
                        color: isDark
                            ? Colors.white.withValues(alpha: 0.12)
                            : Colors.white.withValues(alpha: 0.75),
                        borderRadius: BorderRadius.circular(10),
                        border: Border.all(
                          color: isDark
                              ? Colors.white.withValues(alpha: 0.1)
                              : Colors.white.withValues(alpha: 0.4),
                        ),
                      ),
                      child: Text(
                        label,
                        style: TextStyle(
                          fontSize: 13,
                          fontWeight: FontWeight.w500,
                          color: isDark ? Colors.white : Colors.grey.shade800,
                        ),
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 12),
                _buildFabButton(
                  isDark: isDark,
                  colorScheme: colorScheme,
                  onTap: onTap,
                  child: Icon(icon, size: 20, color: colorScheme.primary),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  /// 统一的毛玻璃圆形按钮
  Widget _buildFabButton({
    required bool isDark,
    required ColorScheme colorScheme,
    required VoidCallback onTap,
    required Widget child,
  }) {
    const size = 44.0;
    const radius = 22.0;

    return ClipRRect(
      borderRadius: BorderRadius.circular(radius),
      child: BackdropFilter(
        filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
        child: Container(
          width: size,
          height: size,
          decoration: BoxDecoration(
            color: colorScheme.primary.withValues(alpha: isDark ? 0.2 : 0.12),
            borderRadius: BorderRadius.circular(radius),
            border: Border.all(
              color: colorScheme.primary.withValues(alpha: isDark ? 0.25 : 0.2),
            ),
          ),
          child: Material(
            color: Colors.transparent,
            child: InkWell(
              borderRadius: BorderRadius.circular(radius),
              onTap: onTap,
              child: Center(child: child),
            ),
          ),
        ),
      ),
    );
  }

  // ---- Body ----

  Widget _buildBody(BuildContext context) {
    final isDesktop = MediaQuery.of(context).size.width >= 1000;
    final child = _buildFileList(context);

    if (!isDesktop || !Platform.isWindows && !Platform.isLinux && !Platform.isMacOS) {
      return child;
    }

    return DropTarget(
      onDragEntered: (_) => setState(() => _isDraggingOver = true),
      onDragExited: (_) => setState(() => _isDraggingOver = false),
      onDragDone: (details) {
        setState(() => _isDraggingOver = false);
        _handleDroppedFiles(details.files);
      },
      child: Stack(
        children: [
          child,
          if (_isDraggingOver)
            IgnorePointer(
              child: Container(
                decoration: BoxDecoration(
                  border: Border.all(
                    color: Theme.of(context).colorScheme.primary,
                    width: 3,
                    strokeAlign: BorderSide.strokeAlignOutside,
                  ),
                  borderRadius: BorderRadius.circular(8),
                  color: Theme.of(context).colorScheme.surface.withValues(alpha: 0.85),
                ),
                child: Center(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Icon(LucideIcons.upload, size: 48, color: Theme.of(context).colorScheme.primary),
                      const SizedBox(height: 12),
                      Text(
                        '释放文件以上传到当前目录',
                        style: TextStyle(
                          color: Theme.of(context).colorScheme.primary,
                          fontSize: 16,
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }

  void _handleDroppedFiles(List<XFile> droppedFiles) {
    final files = <File>[];
    for (final xFile in droppedFiles) {
      final path = xFile.path;
      if (path.isNotEmpty) {
        files.add(File(path));
      }
    }
    if (files.isEmpty) return;

    final uploadManager = Provider.of<UploadManagerProvider>(context, listen: false);
    final fileManager = Provider.of<FileManagerProvider>(context, listen: false);
    uploadManager.markShouldShowDialog();
    uploadManager.startUpload(files, fileManager.currentPath);
    ToastHelper.info('已添加 ${files.length} 个文件到上传队列');
  }

  Widget _buildFileList(BuildContext context) {
    return Consumer<FileManagerProvider>(
      builder: (context, fileManager, child) {
        if (fileManager.isLoading) {
          return const Center(child: CircularProgressIndicator());
        }

        if (fileManager.errorMessage != null) {
          return _buildErrorView(context, fileManager);
        }

        if (fileManager.files.isEmpty) {
          return EmptyFolderView(currentPath: fileManager.currentPath);
        }

        if (fileManager.viewType == FileViewType.list) {
          return _buildListView(context, fileManager);
        }

        return _buildGridView(context, fileManager);
      },
    );
  }

  Widget _buildErrorView(BuildContext context, FileManagerProvider fileManager) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.error_outline, size: 64, color: Theme.of(context).colorScheme.error),
          const SizedBox(height: 16),
          Text(
            fileManager.errorMessage!,
            textAlign: TextAlign.center,
            style: TextStyle(color: Theme.of(context).hintColor),
          ),
          const SizedBox(height: 16),
          FilledButton(
            onPressed: () => fileManager.loadFiles(),
            child: const Text('重试'),
          ),
        ],
      ),
    );
  }

  Future<void> _onRefresh(FileManagerProvider fileManager) async {
    final result = await fileManager.refreshFiles();
    if (!mounted) return;
    if (fileManager.errorMessage != null) {
      ToastHelper.error(fileManager.errorMessage!);
      return;
    }
    if (result.isUnchanged) {
      ToastHelper.info('列表已是最新');
    } else {
      final parts = <String>[];
      if (result.added > 0) parts.add('新增 ${result.added} 项');
      if (result.removed > 0) parts.add('移除 ${result.removed} 项');
      if (result.updated > 0) parts.add('更新 ${result.updated} 项');
      ToastHelper.success('已刷新：${parts.join('，')}');
    }
  }

  Widget _buildListView(BuildContext context, FileManagerProvider fileManager) {
    final isDesktop = MediaQuery.of(context).size.width >= 1000;
    final showCheckbox = fileManager.hasSelection;

    return Column(
      children: [
        if (isDesktop) FileListHeader(showCheckbox: showCheckbox),
        Expanded(
          child: RefreshIndicator(
            onRefresh: () => _onRefresh(fileManager),
            child: NotificationListener<ScrollNotification>(
              onNotification: _onScrollNotification,
              child: ListView.builder(
                key: PageStorageKey('files_list_${fileManager.currentPath}'),
                cacheExtent: 900,
                keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
                itemCount: fileManager.files.length,
                itemBuilder: (context, index) {
                  final file = fileManager.files[index];
                  final isSelected = fileManager.selectedFiles.contains(file.path);

                  return FileListItem(
                    key: ValueKey('file_${file.id}'),
                    file: file,
                    isSelected: isSelected,
                    isHighlighted: file.path == fileManager.highlightPath,
                    showCheckbox: showCheckbox,
                    index: index,
                    isDesktop: isDesktop,
                    onTap: () {
                      _hideFab();
                      _scheduleShowFab();
                      if (showCheckbox) {
                        fileManager.toggleSelection(file.path);
                      } else if (file.isFolder) {
                        fileManager.enterFolder(file.relativePath);
                      } else {
                        _openFile(context, file);
                      }
                    },
                    onSelect: () => fileManager.toggleSelection(file.path),
                    onDownload: !file.isFolder ? () => _downloadFile(context, fileManager, file) : null,
                    onOpenInBrowser: !file.isFolder ? () => _openInBrowser(context, file) : null,
                    onOpenInCloudreveApp: !file.isFolder ? () => _openInCloudreveApp(context, file) : null,
                    onRename: () => FileOperationDialogs.showRenameDialog(context, fileManager, file),
                    onMove: () => FileOperationDialogs.showMoveDialog(context, fileManager, file, false),
                    onCopy: () => FileOperationDialogs.showMoveDialog(context, fileManager, file, true),
                    onShare: () => FileOperationDialogs.showShareDialog(context, file),
                    onDelete: () => FileOperationDialogs.showDeleteSingleConfirmation(context, fileManager, file),
                    onInfo: () => _showFileInfo(file),
                  );
                },
              ),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildGridView(BuildContext context, FileManagerProvider fileManager) {
    final screenWidth = MediaQuery.sizeOf(context).width;
    final padding = 16.0;
    final spacing = 16.0;
    final availableWidth = screenWidth - padding * 2;

    int crossAxisCount;
    if (screenWidth < 400) {
      crossAxisCount = 2;
    } else if (screenWidth < 600) {
      crossAxisCount = 3;
    } else if (screenWidth < 900) {
      crossAxisCount = 4;
    } else {
      crossAxisCount = 5;
    }

    final itemWidth = (availableWidth - spacing * (crossAxisCount - 1)) / crossAxisCount;
    final childAspectRatio = itemWidth / 160;
    final showCheckbox = fileManager.hasSelection;

    return RefreshIndicator(
      onRefresh: () => _onRefresh(fileManager),
      child: NotificationListener<ScrollNotification>(
        onNotification: _onScrollNotification,
        child: GridView.builder(
          key: PageStorageKey('files_grid_${fileManager.currentPath}'),
          cacheExtent: 1100,
          keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
          padding: const EdgeInsets.all(8),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: crossAxisCount,
            mainAxisSpacing: spacing / 2,
            crossAxisSpacing: spacing / 2,
            childAspectRatio: childAspectRatio,
          ),
          itemCount: fileManager.files.length,
          itemBuilder: (context, index) {
            final file = fileManager.files[index];
            final isSelected = fileManager.selectedFiles.contains(file.path);

            return FileGridItem(
              key: ValueKey('file_grid_${file.id}'),
              file: file,
              isSelected: isSelected,
              isHighlighted: file.path == fileManager.highlightPath,
              showCheckbox: showCheckbox,
              contextHint: fileManager.contextHint,
              onTap: () {
                _hideFab();
                _scheduleShowFab();
                if (showCheckbox) {
                  fileManager.toggleSelection(file.path);
                } else if (file.isFolder) {
                  fileManager.enterFolder(file.relativePath);
                } else {
                  _openFile(context, file);
                }
              },
              onSelect: () => fileManager.toggleSelection(file.path),
              onDownload: !file.isFolder ? () => _downloadFile(context, fileManager, file) : null,
              onOpenInBrowser: !file.isFolder ? () => _openInBrowser(context, file) : null,
              onOpenInCloudreveApp: !file.isFolder ? () => _openInCloudreveApp(context, file) : null,
              onRename: () => FileOperationDialogs.showRenameDialog(context, fileManager, file),
              onMove: () => FileOperationDialogs.showMoveDialog(context, fileManager, file, false),
              onCopy: () => FileOperationDialogs.showMoveDialog(context, fileManager, file, true),
              onShare: () => FileOperationDialogs.showShareDialog(context, file),
              onDelete: () => FileOperationDialogs.showDeleteSingleConfirmation(context, fileManager, file),
              onInfo: () => _showFileInfo(file),
            );
          },
        ),
      ),
    );
  }

  Widget _buildBottomBar(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final isDesktop = screenWidth >= 1000;

    return Consumer<FileManagerProvider>(
      builder: (context, fileManager, child) {
        if (fileManager.hasSelection) {
          return SelectionToolbar(
            selectionCount: fileManager.selectedFiles.length,
            totalCount: fileManager.files.length,
            onCancel: () => fileManager.clearSelection(),
            onSelectAll: () => fileManager.selectAll(),
            onMore: fileManager.selectedFiles.length == 1
                ? () => _showSelectionMore(
                      fileManager.files.firstWhere(
                        (f) => f.path == fileManager.selectedFiles.first,
                      ),
                      fileManager,
                    )
                : null,
            onMove: () => FileOperationDialogs.showBatchMoveDialog(
                  context,
                  fileManager,
                  fileManager.selectedFiles,
                  false,
                ),
            onCopy: () => FileOperationDialogs.showBatchMoveDialog(
                  context,
                  fileManager,
                  fileManager.selectedFiles,
                  true,
                ),
            onDelete: () => FileOperationDialogs.showDeleteConfirmation(
                  context,
                  fileManager,
                  fileManager.selectedFiles,
                ),
          );
        }

        if (!isDesktop) return const SizedBox.shrink();

        return FileBreadcrumb(
          currentPath: fileManager.currentPath,
          onPathTap: (path) => fileManager.enterFolder(path),
        );
      },
    );
  }

  void _openFile(BuildContext context, FileModel file) {
    if (FileTypeUtils.isImage(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.imagePreview, arguments: file);
    } else if (FileTypeUtils.isPdf(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.pdfPreview, arguments: file);
    } else if (FileTypeUtils.isVideo(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.videoPreview, arguments: file);
    } else if (FileTypeUtils.isAudio(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.audioPreview, arguments: file);
    } else if (FileTypeUtils.isMarkdown(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.markdownPreview, arguments: file);
    } else if (FileTypeUtils.isTextCode(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.documentPreview, arguments: file);
    } else {
      ToastHelper.info('暂不支持预览 ${FileTypeUtils.getFileTypeDescription(file.name)}');
    }
  }

  Future<void> _downloadFile(
    BuildContext context,
    FileManagerProvider fileManager,
    FileModel file,
  ) async {
    final downloadManager = Provider.of<DownloadManagerProvider>(context, listen: false);
    final task = await downloadManager.addDownloadTask(
      fileName: file.name,
      fileUri: file.relativePath,
      fileSize: file.size,
    );

    if (task != null) {
      if (context.mounted) {
        ToastHelper.info('文件已在下载列表中');
      }
      return;
    }

    if (context.mounted) {
      ToastHelper.info('开始下载，查看任务页');
    }
  }

  Future<void> _openInBrowser(BuildContext context, FileModel file) async {
    try {
      final response = await FileService().getDownloadUrls(
        uris: [file.relativePath],
        download: true,
      );

      final urls = response['urls'] as List<dynamic>? ?? [];
      if (urls.isNotEmpty) {
        final urlData = urls[0] as Map<String, dynamic>;
        final url = urlData['url'] as String;

        final uri = Uri.parse(url);
        if (await canLaunchUrl(uri)) {
          await launchUrl(uri, mode: LaunchMode.platformDefault);
        } else {
          if (context.mounted) {
            ToastHelper.error('无法打开链接: $uri');
          }
        }
      }
    } catch (e) {
      if (context.mounted) {
        ToastHelper.failure('获取下载链接失败: $e');
      }
    }
  }

  void _openInCloudreveApp(BuildContext context, FileModel file) {
    Navigator.of(context).pushNamed(
      RouteNames.cloudreveFileApp,
      arguments: {
        'file': file,
      },
    );
  }
}
