import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../data/models/file_model.dart';
import '../../core/utils/date_utils.dart' as date_utils;
import '../../core/utils/file_icon_utils.dart';
import '../../core/utils/file_type_utils.dart';
import '../../services/file_service.dart';
import '../../router/app_router.dart';
import 'toast_helper.dart';

/// 文件/文件夹详情（右侧抽屉）
class FileInfoPanel extends StatefulWidget {
  final FileModel file;
  const FileInfoPanel({super.key, required this.file});

  /// 在指定 context 的 Scaffold 上打开右侧抽屉
  static void show(BuildContext context, FileModel file) {
    Scaffold.of(context).openEndDrawer();
  }

  /// 以 BottomSheet 方式展示文件详情
  static void showAsBottomSheet(BuildContext context, FileModel file) {
    showModalBottomSheet<void>(
      context: context,
      isScrollControlled: true,
      showDragHandle: true,
      builder: (_) => _FileInfoSheet(file: file),
    );
  }

  @override
  State<FileInfoPanel> createState() => _FileInfoPanelState();
}

class _FileInfoPanelState extends State<FileInfoPanel> {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: FileInfoPanelContent(file: widget.file),
    );
  }
}

/// 以 BottomSheet 形式展示的文件详情
class _FileInfoSheet extends StatelessWidget {
  final FileModel file;
  const _FileInfoSheet({required this.file});

  @override
  Widget build(BuildContext context) {
    return DraggableScrollableSheet(
      initialChildSize: 0.7,
      minChildSize: 0.4,
      maxChildSize: 0.95,
      expand: false,
      builder: (context, scrollController) {
        return FileInfoPanelContent(file: file);
      },
    );
  }
}

/// FileInfoPanel 的可复用内容区（不含 Drawer 壳）
class FileInfoPanelContent extends StatefulWidget {
  final FileModel file;
  const FileInfoPanelContent({super.key, required this.file});

  @override
  State<FileInfoPanelContent> createState() => _FileInfoPanelContentState();
}

class _FileInfoPanelContentState extends State<FileInfoPanelContent> {
  FileInfoModel? _fileInfo;
  bool _isLoading = true;
  bool _isCalculatingFolder = false;
  bool _isVersionLoading = false;
  String? _error;

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

  Future<void> _loadFileInfo() async {
    try {
      final response = await FileService().getFileInfo(
        uri: widget.file.relativePath,
        extended: widget.file.isFile,
        folderSummary: false,
      );
      if (mounted) {
        setState(() {
          _fileInfo = FileInfoModel.fromJson(response);
          _isLoading = false;
          _isVersionLoading = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _error = e.toString();
          _isLoading = false;
        });
      }
    }
  }

  Future<void> _calculateFolderSize() async {
    setState(() => _isCalculatingFolder = true);
    try {
      final response = await FileService().getFileInfo(
        uri: widget.file.relativePath,
        extended: true,
        folderSummary: true,
      );
      if (mounted) {
        setState(() {
          _fileInfo = FileInfoModel.fromJson(response);
          _isCalculatingFolder = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() => _isCalculatingFolder = false);
        ToastHelper.failure('计算文件夹大小失败: $e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final colorScheme = theme.colorScheme;

    return Column(
      children: [
        Container(
          padding: const EdgeInsets.only(
            left: 16,
            right: 8,
            top: 8,
            bottom: 12,
          ),
          decoration: BoxDecoration(
            border: Border(
              bottom: BorderSide(color: theme.dividerColor.withValues(alpha: 0.2)),
            ),
          ),
          child: Row(
            children: [
              FileIconUtils.buildIconWidget(
                context: context,
                file: widget.file,
                size: 32,
                iconSize: 18,
                borderRadius: 8,
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Text(
                  widget.file.name,
                  style: theme.textTheme.titleMedium,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              IconButton(
                icon: const Icon(LucideIcons.x),
                onPressed: () => Navigator.of(context).pop(),
              ),
            ],
          ),
        ),
        Expanded(
          child: _isLoading
              ? const Center(child: CircularProgressIndicator())
              : _error != null
                  ? _buildError(theme)
                  : _buildContent(theme, colorScheme),
        ),
      ],
    );
  }

  Widget _buildError(ThemeData theme) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(LucideIcons.alertCircle, size: 48, color: theme.colorScheme.error),
          const SizedBox(height: 12),
          Text('加载失败', style: theme.textTheme.titleSmall),
          const SizedBox(height: 4),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: Text(_error ?? '', style: TextStyle(color: theme.hintColor, fontSize: 12), textAlign: TextAlign.center),
          ),
          const SizedBox(height: 12),
          FilledButton.tonal(onPressed: _loadFileInfo, child: const Text('重试')),
        ],
      ),
    );
  }

  Widget _buildContent(ThemeData theme, ColorScheme colorScheme) {
    final file = _fileInfo?.file ?? widget.file;
    final typeLabel = file.isFolder
        ? '文件夹'
        : FileIconUtils.getFileTypeLabel(file.name);
    final extendedInfo = _fileInfo?.extendedInfo;
    final versionEntities = extendedInfo?.entities
            ?.where((e) => e.type == 0)
            .toList() ??
        [];

    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
            decoration: BoxDecoration(
              color: colorScheme.primaryContainer,
              borderRadius: BorderRadius.circular(6),
            ),
            child: Text(
              typeLabel,
              style: TextStyle(
                fontSize: 12,
                color: colorScheme.onPrimaryContainer,
                fontWeight: FontWeight.w500,
              ),
            ),
          ),
          const SizedBox(height: 16),
          _buildInfoRow(LucideIcons.folderOpen, '位置', Uri.decodeComponent(file.relativePath)),
          if (file.isFile)
            _buildInfoRow(
              LucideIcons.hardDrive,
              '大小',
              date_utils.DateUtils.formatFileSize(file.size),
            ),
          _buildInfoRow(LucideIcons.calendarPlus, '创建时间', date_utils.DateUtils.formatDateTime(file.createdAt)),
          _buildInfoRow(LucideIcons.calendar, '修改时间', date_utils.DateUtils.formatDateTime(file.updatedAt)),
          if (file.owned != null)
            _buildInfoRow(LucideIcons.shield, '所有者', file.owned! ? '是' : '否'),

          if (file.isFile && extendedInfo != null) ...[
            const SizedBox(height: 12),
            Divider(color: theme.dividerColor.withValues(alpha: 0.3)),
            const SizedBox(height: 8),
            Text('扩展信息', style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
            const SizedBox(height: 8),
            _buildInfoRow(LucideIcons.fingerprint, '文件ID', file.id),
            if (file.primaryEntity != null)
              _buildInfoRow(LucideIcons.hash, '主版本', file.primaryEntity!),
            if (extendedInfo.storagePolicy != null)
              _buildInfoRow(
                LucideIcons.server,
                '存储策略',
                '${extendedInfo.storagePolicy!.name} (${extendedInfo.storagePolicy!.type})',
              ),
            if (extendedInfo.storageUsed != null)
              _buildInfoRow(
                LucideIcons.database,
                '总占用',
                date_utils.DateUtils.formatFileSize(extendedInfo.storageUsed!),
              ),
          ],

          if (file.isFile && versionEntities.isNotEmpty) ...[
            const SizedBox(height: 12),
            Divider(color: theme.dividerColor.withValues(alpha: 0.3)),
            const SizedBox(height: 8),
            _buildVersionSection(theme, colorScheme, versionEntities),
          ],

          if (file.isFolder) ...[
            const SizedBox(height: 12),
            Divider(color: theme.dividerColor.withValues(alpha: 0.3)),
            const SizedBox(height: 8),
            Text('文件夹信息', style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
            const SizedBox(height: 8),
            _buildFolderSummary(theme, colorScheme),
          ],
        ],
      ),
    );
  }

  Widget _buildVersionSection(
    ThemeData theme,
    ColorScheme colorScheme,
    List<EntityModel> entities,
  ) {
    final file = _fileInfo!.file;
    final primaryEntity = file.primaryEntity;
    final isPreviewable = FileTypeUtils.isPreviewable(file.name);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Text('版本历史', style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w600)),
            const SizedBox(width: 8),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1),
              decoration: BoxDecoration(
                color: colorScheme.primaryContainer,
                borderRadius: BorderRadius.circular(6),
              ),
              child: Text(
                '${entities.length}',
                style: TextStyle(
                  fontSize: 11,
                  color: colorScheme.onPrimaryContainer,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ),
          ],
        ),
        const SizedBox(height: 8),
        ...entities.asMap().entries.map((entry) {
          final index = entry.key;
          final entity = entry.value;
          final isCurrent = entity.id == primaryEntity;
          final versionNumber = entities.length - index;
          return _buildVersionItem(
            theme,
            colorScheme,
            entity: entity,
            versionNumber: versionNumber,
            isCurrent: isCurrent,
            isPreviewable: isPreviewable,
            file: file,
          );
        }),
      ],
    );
  }

  Widget _buildVersionItem(
    ThemeData theme,
    ColorScheme colorScheme, {
    required EntityModel entity,
    required int versionNumber,
    required bool isCurrent,
    required bool isPreviewable,
    required FileModel file,
  }) {
    final shortId = entity.id.length > 6 ? entity.id.substring(0, 6) : entity.id;
    final createdBy = entity.createdBy?.nickname ?? '未知';

    return Container(
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 4),
      decoration: BoxDecoration(
        color: isCurrent
            ? colorScheme.primaryContainer.withValues(alpha: 0.15)
            : null,
        border: Border(
          bottom: BorderSide(color: theme.dividerColor.withValues(alpha: 0.15)),
        ),
      ),
      child: LayoutBuilder(
        builder: (context, constraints) {
          final isNarrow = constraints.maxWidth < 380;

          final actionButtons = <Widget>[
            if (isPreviewable)
              _buildVersionActionButton(
                icon: LucideIcons.externalLink,
                tooltip: '打开',
                onPressed: _isVersionLoading ? null : () => _openVersion(entity),
              ),
            _buildVersionActionButton(
              icon: LucideIcons.download,
              tooltip: '下载',
              onPressed: _isVersionLoading ? null : () => _downloadVersion(entity),
            ),
            if (!isCurrent) ...[
              _buildVersionActionButton(
                icon: LucideIcons.pin,
                tooltip: '设为当前版本',
                onPressed: _isVersionLoading ? null : () => _setCurrentVersion(entity),
              ),
              _buildVersionActionButton(
                icon: LucideIcons.trash2,
                tooltip: '删除',
                color: colorScheme.error,
                onPressed: _isVersionLoading ? null : () => _deleteVersion(entity),
              ),
            ],
          ];

          final versionBadge = Container(
            padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
            decoration: BoxDecoration(
              color: isCurrent
                  ? colorScheme.primaryContainer
                  : colorScheme.surfaceContainerHighest,
              borderRadius: BorderRadius.circular(6),
            ),
            child: Text(
              isCurrent ? '当前' : 'v$versionNumber',
              style: TextStyle(
                fontSize: 11,
                color: isCurrent
                    ? colorScheme.onPrimaryContainer
                    : theme.hintColor,
                fontWeight: FontWeight.w600,
              ),
            ),
          );

          final versionInfo = Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                GestureDetector(
                  onTap: () => _showVersionDetail(entity),
                  onLongPress: () => _showVersionDetail(entity),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        '$shortId · ${date_utils.DateUtils.formatFileSize(entity.size)}',
                        style: theme.textTheme.bodyMedium?.copyWith(
                          fontWeight: FontWeight.w500,
                        ),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                      const SizedBox(height: 1),
                      Text(
                        '${date_utils.DateUtils.formatDateTime(entity.createdAt)} · $createdBy',
                        style: const TextStyle(fontSize: 11, color: null)
                            .copyWith(color: theme.hintColor),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                  ),
                ),
                if (isNarrow) ...[
                  const SizedBox(height: 4),
                  Row(children: actionButtons),
                ],
              ],
            ),
          );

          if (isNarrow) {
            return Row(
              children: [versionBadge, const SizedBox(width: 8), versionInfo],
            );
          }

          return Row(
            children: [
              versionBadge,
              const SizedBox(width: 8),
              versionInfo,
              ...actionButtons,
            ],
          );
        },
      ),
    );
  }

  void _showVersionDetail(EntityModel entity) {
    final createdBy = entity.createdBy;
    showDialog(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('版本详情'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildInfoRow(LucideIcons.hash, 'ID', entity.id),
            _buildInfoRow(LucideIcons.hardDrive, '大小', date_utils.DateUtils.formatFileSize(entity.size)),
            _buildInfoRow(LucideIcons.calendarPlus, '创建时间', date_utils.DateUtils.formatDateTime(entity.createdAt)),
            if (createdBy != null) ...[
              _buildInfoRow(LucideIcons.user, '创建者', createdBy.nickname),
              _buildInfoRow(LucideIcons.fingerprint, '创建者ID', createdBy.id),
            ],
            if (entity.storagePolicy != null)
              _buildInfoRow(LucideIcons.server, '存储策略', '${entity.storagePolicy!.name} (${entity.storagePolicy!.type})'),
            if (entity.encryptedWith != null)
              _buildInfoRow(LucideIcons.lock, '加密', entity.encryptedWith!),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(dialogContext).pop(),
            child: const Text('关闭'),
          ),
        ],
      ),
    );
  }

  Widget _buildVersionActionButton({
    required IconData icon,
    required String tooltip,
    Color? color,
    required VoidCallback? onPressed,
  }) {
    return IconButton(
      icon: Icon(icon, size: 16, color: color),
      onPressed: onPressed,
      tooltip: tooltip,
      style: IconButton.styleFrom(
        padding: const EdgeInsets.all(4),
        minimumSize: const Size(28, 28),
      ),
    );
  }

  void _openVersion(EntityModel entity) {
    final file = _fileInfo!.file;
    if (!FileTypeUtils.isPreviewable(file.name)) {
      ToastHelper.info('暂不支持预览此文件类型');
      return;
    }

    final args = {'file': file, 'entityId': entity.id};

    if (FileTypeUtils.isImage(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.imagePreview, arguments: args);
    } else if (FileTypeUtils.isPdf(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.pdfPreview, arguments: args);
    } else if (FileTypeUtils.isVideo(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.videoPreview, arguments: args);
    } else if (FileTypeUtils.isAudio(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.audioPreview, arguments: args);
    } else if (FileTypeUtils.isMarkdown(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.markdownPreview, arguments: args);
    } else if (FileTypeUtils.isTextCode(file.name)) {
      Navigator.of(context).pushNamed(RouteNames.documentPreview, arguments: args);
    }
  }

  Future<void> _downloadVersion(EntityModel entity) async {
    try {
      final response = await FileService().getDownloadUrls(
        uris: [widget.file.relativePath],
        entity: entity.id,
        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 (mounted) ToastHelper.error('无法打开下载链接');
        }
      } else {
        if (mounted) ToastHelper.error('获取下载链接失败');
      }
    } catch (e) {
      if (mounted) ToastHelper.failure('获取下载链接失败: $e');
    }
  }

  Future<void> _setCurrentVersion(EntityModel entity) async {
    setState(() => _isVersionLoading = true);
    try {
      await FileService().setFileVersion(
        uri: widget.file.relativePath,
        version: entity.id,
      );
      if (mounted) {
        ToastHelper.success('已设为当前版本');
        _loadFileInfo();
      }
    } catch (e) {
      if (mounted) {
        setState(() => _isVersionLoading = false);
        ToastHelper.failure('操作失败: $e');
      }
    }
  }

  Future<void> _deleteVersion(EntityModel entity) async {
    final colorScheme = Theme.of(context).colorScheme;
    final shortId = entity.id.length > 6 ? entity.id.substring(0, 6) : entity.id;
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('删除版本'),
        content: Text('确定要删除版本 "$shortId" (${date_utils.DateUtils.formatFileSize(entity.size)}) 吗？'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(dialogContext).pop(false),
            child: const Text('取消'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(dialogContext).pop(true),
            style: FilledButton.styleFrom(backgroundColor: colorScheme.error),
            child: const Text('删除'),
          ),
        ],
      ),
    );

    if (confirmed != true) return;

    setState(() => _isVersionLoading = true);
    try {
      await FileService().deleteFileVersion(
        uri: widget.file.relativePath,
        version: entity.id,
      );
      if (mounted) {
        ToastHelper.success('版本已删除');
        _loadFileInfo();
      }
    } catch (e) {
      if (mounted) {
        setState(() => _isVersionLoading = false);
        ToastHelper.failure('删除失败: $e');
      }
    }
  }

  Widget _buildFolderSummary(ThemeData theme, ColorScheme colorScheme) {
    final summary = _fileInfo?.folderSummary;

    if (summary != null) {
      return Column(
        children: [
          _buildInfoRow(LucideIcons.file, '包含文件', '${summary.files}'),
          _buildInfoRow(LucideIcons.folder, '包含文件夹', '${summary.folders}'),
          _buildInfoRow(LucideIcons.hardDrive, '总大小', date_utils.DateUtils.formatFileSize(summary.size)),
          if (!summary.completed)
            Padding(
              padding: const EdgeInsets.only(top: 8),
              child: Row(
                children: [
                  Icon(LucideIcons.alertCircle, size: 14, color: theme.colorScheme.error),
                  const SizedBox(width: 6),
                  Text('计算未完成，结果可能不完整', style: TextStyle(fontSize: 12, color: theme.colorScheme.error)),
                ],
              ),
            ),
          const SizedBox(height: 8),
          Text(
            '计算于 ${date_utils.DateUtils.formatDateTime(summary.calculatedAt)}',
            style: TextStyle(fontSize: 11, color: theme.hintColor),
          ),
        ],
      );
    }

    return _isCalculatingFolder
        ? const Center(child: Padding(padding: EdgeInsets.all(16), child: CircularProgressIndicator()))
        : SizedBox(
            width: double.infinity,
            child: OutlinedButton.icon(
              onPressed: _calculateFolderSize,
              icon: const Icon(LucideIcons.calculator, size: 16),
              label: const Text('计算文件夹大小'),
            ),
          );
  }

  Widget _buildInfoRow(IconData icon, String label, String value) {
    final theme = Theme.of(context);
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Icon(icon, size: 16, color: theme.hintColor),
          const SizedBox(width: 8),
          SizedBox(
            width: 72,
            child: Text(label, style: TextStyle(fontSize: 13, color: theme.hintColor)),
          ),
          Expanded(
            child: SelectableText(
              value,
              style: const TextStyle(fontSize: 13),
            ),
          ),
        ],
      ),
    );
  }
}
