import 'package:cloudreve4_flutter/presentation/providers/auth_provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/download_manager_provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/file_manager_provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/navigation_provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/sync_provider.dart';
import 'package:cloudreve4_flutter/presentation/providers/upload_manager_provider.dart';
import 'package:cloudreve4_flutter/presentation/widgets/announcement_dialog.dart';
import 'package:cloudreve4_flutter/presentation/widgets/gesture_handler_mixin.dart';
import 'package:cloudreve4_flutter/presentation/widgets/glassmorphism_container.dart';
import 'package:cloudreve4_flutter/presentation/widgets/user_avatar.dart';
import 'package:cloudreve4_flutter/services/announcement_service.dart';
import 'package:cloudreve4_flutter/services/dialog_queue_service.dart';
import 'package:cloudreve4_flutter/services/share_link_service.dart';
import 'package:cloudreve4_flutter/presentation/pages/share/share_link_page.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart';
import '../../../router/app_router.dart';
import '../files/files_page.dart';
import '../overview/overview_page.dart';
import '../sync/sync_page.dart';
import '../tasks/tasks_page.dart';
import '../profile/profile_page.dart';

class _ShellPageSlot extends StatefulWidget {
  final Widget child;

  const _ShellPageSlot({required this.child});

  @override
  State<_ShellPageSlot> createState() => _ShellPageSlotState();
}

class _ShellPageSlotState extends State<_ShellPageSlot>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }
}

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

  @override
  State<AppShell> createState() => _AppShellState();
}

class _AppShellState extends State<AppShell>
    with GestureHandlerMixin, TickerProviderStateMixin, WidgetsBindingObserver {
  final Set<int> _visitedPageIndexes = <int>{0};
  late AnimationController _syncSpinController;
  String? _lastClipboardShareId;

  bool get _showSyncTab =>
      defaultTargetPlatform != TargetPlatform.android &&
      defaultTargetPlatform != TargetPlatform.iOS;

  List<Widget> get _pages => _showSyncTab
      ? [
          const OverviewPage(),
          const FilesPage(),
          const TasksPage(),
          const SyncPage(),
          const ProfilePage(),
        ]
      : [
          const OverviewPage(),
          const FilesPage(),
          const TasksPage(),
          const ProfilePage(),
        ];

  int _clampedIndex(int index) {
    final maxIndex = _pages.length - 1;
    if (index < 0) return 0;
    if (index > maxIndex) return maxIndex;
    return index;
  }

  @override
  void initState() {
    super.initState();
    _syncSpinController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _showPostLoginAnnouncement();
      _checkClipboardShareLink();
    });
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _syncSpinController.dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _checkClipboardShareLink();
    }
  }

  Future<void> _showPostLoginAnnouncement() async {
    final authProvider = context.read<AuthProvider>();
    if (!authProvider.isAuthenticated) return;

    try {
      final service = AnnouncementService.instance;
      final announcement = await service.getChangedSiteNotice();
      if (!mounted || announcement == null) return;

      await DialogQueueService.instance.enqueue<void>(() async {
        if (!mounted) return;

        await AnnouncementDialog.show(
          context,
          title: announcement.title,
          html: announcement.html,
          baseUrl: announcement.baseUrl,
        );

        await service.markDismissed(announcement);
      });
    } catch (_) {
      // Announcement checks should never block the shell.
    }
  }

  Future<void> _checkClipboardShareLink() async {
    await Future<void>.delayed(const Duration(milliseconds: 650));
    if (!mounted) return;

    try {
      final data = await Clipboard.getData(Clipboard.kTextPlain);
      final candidate = ShareLinkService.instance.parseShareLink(data?.text);

      if (candidate == null) return;
      if (_lastClipboardShareId == candidate.id) return;

      _lastClipboardShareId = candidate.id;

      await DialogQueueService.instance.enqueue<void>(() async {
        if (!mounted) return;

        final open = await showDialog<bool>(
          context: context,
          builder: (ctx) => AlertDialog(
            title: const Text('检测到分享链接'),
            content: Text(
              '是否打开这个文件分享？\n\n${candidate.url}',
              maxLines: 5,
              overflow: TextOverflow.ellipsis,
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(ctx).pop(false),
                child: const Text('忽略'),
              ),
              FilledButton(
                onPressed: () => Navigator.of(ctx).pop(true),
                child: const Text('打开'),
              ),
            ],
          ),
        );

        if (open == true && mounted) {
          await Navigator.of(context).push(
            MaterialPageRoute(
              builder: (_) => ShareLinkPage(candidate: candidate),
            ),
          );
        }
      });
    } catch (_) {
      // Clipboard access failures should not affect the shell.
    }
  }

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

    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, result) async {
        if (!didPop) {
          final navProvider = Provider.of<NavigationProvider>(
            context,
            listen: false,
          );
          final fileManager = Provider.of<FileManagerProvider>(
            context,
            listen: false,
          );

          if (navProvider.currentIndex == 1 && fileManager.currentPath != '/') {
            await fileManager.goBack();
          } else if (navProvider.currentIndex != 0 &&
              navProvider.currentIndex != 1) {
            navProvider.setIndex(0);
          } else {
            await checkExitApp(context);
          }
        }
      },
      child: Consumer<NavigationProvider>(
        builder: (context, navProvider, _) {
          if (isDesktop) {
            return _buildDesktopLayout(context, navProvider);
          }
          return _buildMobileLayout(context, navProvider);
        },
      ),
    );
  }

  Widget _buildPageContent(BuildContext context, int currentIndex) {
    final pages = _pages;
    final visibleIndex = _clampedIndex(currentIndex);
    _visitedPageIndexes.add(visibleIndex);

    return RepaintBoundary(
      child: IndexedStack(
        index: visibleIndex,
        children: List.generate(pages.length, (index) {
          if (!_visitedPageIndexes.contains(index)) {
            return const SizedBox.shrink();
          }
          return _ShellPageSlot(child: pages[index]);
        }),
      ),
    );
  }

  Widget _buildSyncIcon({required bool isSelected, required double size}) {
    return Consumer<SyncProvider>(
      builder: (context, sync, _) {
        final hasWorkers = sync.activeWorkerCount > 0;

        if (hasWorkers && !_syncSpinController.isAnimating) {
          _syncSpinController.repeat();
        } else if (!hasWorkers && _syncSpinController.isAnimating) {
          _syncSpinController.stop();
          _syncSpinController.value = 0;
        }

        final icon = Icon(
          LucideIcons.refreshCw,
          size: size,
          weight: isSelected ? 700 : 400,
        );

        if (!hasWorkers) return icon;

        return ListenableBuilder(
          listenable: _syncSpinController,
          builder: (context, child) {
            return Transform.rotate(
              angle: _syncSpinController.value * 2 * 3.14159265,
              child: child,
            );
          },
          child: icon,
        );
      },
    );
  }

  Widget _buildMobileLayout(
    BuildContext context,
    NavigationProvider navProvider,
  ) {
    return Scaffold(
      body: _buildPageContent(context, navProvider.currentIndex),
      bottomNavigationBar: GlassmorphismContainer(
        borderRadius: 0,
        child: Consumer2<UploadManagerProvider, DownloadManagerProvider>(
          builder: (context, uploadManager, downloadManager, _) {
            final activeCount =
                uploadManager.activeTasks.length +
                downloadManager.downloadingCount;

            return NavigationBar(
              height: 64,
              selectedIndex: _clampedIndex(navProvider.currentIndex),
              onDestinationSelected: (i) => navProvider.setIndex(i),
              destinations: [
                const NavigationDestination(
                  icon: Icon(LucideIcons.layoutDashboard),
                  selectedIcon: Icon(LucideIcons.layoutDashboard, weight: 700),
                  label: '概览',
                ),
                const NavigationDestination(
                  icon: Icon(LucideIcons.folder),
                  selectedIcon: Icon(LucideIcons.folder, weight: 700),
                  label: '文件',
                ),
                NavigationDestination(
                  icon: Badge(
                    isLabelVisible: activeCount > 0,
                    label: Text('$activeCount'),
                    child: const Icon(LucideIcons.listChecks),
                  ),
                  selectedIcon: Badge(
                    isLabelVisible: activeCount > 0,
                    label: Text('$activeCount'),
                    child: const Icon(LucideIcons.listChecks, weight: 700),
                  ),
                  label: '任务',
                ),
                if (_showSyncTab)
                  NavigationDestination(
                    icon: Consumer<SyncProvider>(
                      builder: (context, sync, _) {
                        final count = sync.activeWorkerCount;
                        return Badge(
                          isLabelVisible: count > 0,
                          label: Text('$count'),
                          child: _buildSyncIcon(isSelected: false, size: 24),
                        );
                      },
                    ),
                    selectedIcon: Consumer<SyncProvider>(
                      builder: (context, sync, _) {
                        final count = sync.activeWorkerCount;
                        return Badge(
                          isLabelVisible: count > 0,
                          label: Text('$count'),
                          child: _buildSyncIcon(isSelected: true, size: 24),
                        );
                      },
                    ),
                    label: '同步',
                  ),
                const NavigationDestination(
                  icon: Icon(LucideIcons.user),
                  selectedIcon: Icon(LucideIcons.user, weight: 700),
                  label: '我的',
                ),
              ],
            );
          },
        ),
      ),
    );
  }

  Widget _buildDesktopLayout(
    BuildContext context,
    NavigationProvider navProvider,
  ) {
    final theme = Theme.of(context);
    final authProvider = context.watch<AuthProvider>();
    final user = authProvider.user;
    final displayName = user?.nickname ?? '用户';

    return Scaffold(
      body: Row(
        children: [
          NavigationRail(
            selectedIndex: _clampedIndex(navProvider.currentIndex),
            onDestinationSelected: (i) => navProvider.setIndex(i),
            leading: Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: GestureDetector(
                onTap: () => navProvider.setIndex(_pages.length - 1),
                child: Container(
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: navProvider.currentIndex == _pages.length - 1
                        ? Border.all(
                            color: theme.colorScheme.primary,
                            width: 2.5,
                          )
                        : null,
                  ),
                  child: UserAvatar(
                    userId: user?.id ?? '',
                    email: user?.email,
                    displayName: displayName,
                    radius: 20,
                  ),
                ),
              ),
            ),
            destinations: [
              const NavigationRailDestination(
                icon: Icon(LucideIcons.layoutDashboard),
                selectedIcon: Icon(LucideIcons.layoutDashboard, weight: 700),
                label: Text('概览'),
              ),
              const NavigationRailDestination(
                icon: Icon(LucideIcons.folder),
                selectedIcon: Icon(LucideIcons.folder, weight: 700),
                label: Text('文件'),
              ),
              NavigationRailDestination(
                icon: Consumer2<UploadManagerProvider, DownloadManagerProvider>(
                  builder: (context, uploadManager, downloadManager, _) {
                    final activeCount =
                        uploadManager.activeTasks.length +
                        downloadManager.downloadingCount;
                    return Badge(
                      isLabelVisible: activeCount > 0,
                      label: Text('$activeCount'),
                      child: const Icon(LucideIcons.listChecks),
                    );
                  },
                ),
                selectedIcon: const Icon(LucideIcons.listChecks, weight: 700),
                label: const Text('任务'),
              ),
              if (_showSyncTab)
                NavigationRailDestination(
                  icon: Consumer<SyncProvider>(
                    builder: (context, sync, _) {
                      final count = sync.activeWorkerCount;
                      return Badge(
                        isLabelVisible: count > 0,
                        label: Text('$count'),
                        child: _buildSyncIcon(isSelected: false, size: 24),
                      );
                    },
                  ),
                  selectedIcon: Consumer<SyncProvider>(
                    builder: (context, sync, _) {
                      final count = sync.activeWorkerCount;
                      return Badge(
                        isLabelVisible: count > 0,
                        label: Text('$count'),
                        child: _buildSyncIcon(isSelected: true, size: 24),
                      );
                    },
                  ),
                  label: const Text('同步'),
                ),
              const NavigationRailDestination(
                icon: Icon(LucideIcons.user),
                selectedIcon: Icon(LucideIcons.user, weight: 700),
                label: Text('我的'),
              ),
            ],
            trailing: Expanded(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  const Divider(indent: 12, endIndent: 12),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.share2,
                    label: '我的分享',
                    onTap: () =>
                        Navigator.of(context).pushNamed(RouteNames.share),
                  ),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.cloud,
                    label: 'WebDAV',
                    onTap: () =>
                        Navigator.of(context).pushNamed(RouteNames.webdav),
                  ),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.download,
                    label: '离线下载',
                    onTap: () => Navigator.of(
                      context,
                    ).pushNamed(RouteNames.remoteDownload),
                  ),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.trash2,
                    label: '回收站',
                    onTap: () =>
                        Navigator.of(context).pushNamed(RouteNames.recycleBin),
                  ),
                  const Divider(indent: 12, endIndent: 12),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.settings,
                    label: '设置',
                    onTap: () =>
                        Navigator.of(context).pushNamed(RouteNames.settings),
                  ),
                  _buildSecondaryNavItem(
                    context,
                    icon: LucideIcons.logOut,
                    label: '退出登录',
                    onTap: () => _handleLogout(context),
                  ),
                  const SizedBox(height: 12),
                ],
              ),
            ),
          ),
          const VerticalDivider(thickness: 1, width: 1),
          Expanded(child: _buildPageContent(context, navProvider.currentIndex)),
        ],
      ),
    );
  }

  Widget _buildSecondaryNavItem(
    BuildContext context, {
    required IconData icon,
    required String label,
    required VoidCallback onTap,
  }) {
    final theme = Theme.of(context);
    return InkWell(
      onTap: onTap,
      customBorder: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(8),
      ),
      child: Tooltip(
        message: label,
        preferBelow: false,
        child: Padding(
          padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
          child: Icon(icon, size: 22, color: theme.hintColor),
        ),
      ),
    );
  }

  Future<void> _handleLogout(BuildContext context) async {
    final authProvider = Provider.of<AuthProvider>(context, listen: false);
    final fileManager = Provider.of<FileManagerProvider>(
      context,
      listen: false,
    );

    final confirmed = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('退出登录'),
        content: const Text('确定要退出登录吗？'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(dialogContext).pop(false),
            child: const Text('取消'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(dialogContext).pop(true),
            child: const Text('退出'),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      await authProvider.logout();
      fileManager.clearFiles();
      if (context.mounted) {
        Navigator.of(
          context,
        ).pushNamedAndRemoveUntil(RouteNames.login, (route) => false);
      }
    }
  }
}
