import 'dart:async';
import 'dart:ui' show ImageFilter;

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/legacy.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../providers/home_banner_provider.dart';
import '../../providers/di_providers.dart';
import '../../providers/library_overview_provider.dart';
import '../../providers/server_provider.dart';
import '../../providers/session_provider.dart';
import '../../providers/shell_backdrop_provider.dart';
import '../../features/settings/settings_page.dart';
import '../../providers/tmdb_settings_provider.dart';
import '../../providers/sm_account_provider.dart';
import '../../providers/trakt_settings_provider.dart';
import '../theme/app_theme.dart';
import 'server_action_menu.dart';
import 'server_menu_item.dart';
import 'top_drag_area.dart';

const _kSidebarCollapsedKey = 'smplayer.sidebar_collapsed';

const double _kSidebarBlurSigma = 18;


class _SidebarPalette {
  final Color fg;
  final Color fgMuted;
  final Color fgFaint;
  final Color glassTint;
  final Color hairline;

  const _SidebarPalette({
    required this.fg,
    required this.fgMuted,
    required this.fgFaint,
    required this.glassTint,
    required this.hairline,
  });

  static const dark = _SidebarPalette(
    fg: Colors.white,
    fgMuted: Color(0x99FFFFFF),
    fgFaint: Color(0x66FFFFFF),
    glassTint: Color(0x42000000),
    hairline: Color(0x14FFFFFF),
  );

  static const light = _SidebarPalette(
    fg: Color(0xFF1A1A1A),
    fgMuted: Color(0x99000000),
    fgFaint: Color(0x59000000),
    glassTint: Color(0x8CFFFFFF),
    hairline: Color(0x0F000000),
  );

  static const darkSurface = _SidebarPalette(
    fg: Colors.white,
    fgMuted: Color(0x99FFFFFF),
    fgFaint: Color(0x66FFFFFF),
    glassTint: Color(0x14FFFFFF),
    hairline: Color(0x1FFFFFFF),
  );
}

final sidebarCollapsedProvider = StateProvider<bool>((ref) => false);

Future<void> initSidebarState(WidgetRef ref) async {
  final prefs = await SharedPreferences.getInstance();
  final collapsed = prefs.getBool(_kSidebarCollapsedKey) ?? false;
  ref.read(sidebarCollapsedProvider.notifier).state = collapsed;
}

Future<void> _persistSidebarState(bool collapsed) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setBool(_kSidebarCollapsedKey, collapsed);
}

class Sidebar extends ConsumerStatefulWidget {


  final int selectedBranchIndex;


  final void Function(int index, {bool initialLocation}) onNavigateBranch;


  final bool immersiveRoute;


  final String location;

  const Sidebar({
    super.key,
    required this.selectedBranchIndex,
    required this.onNavigateBranch,
    required this.location,
    this.immersiveRoute = false,
  });

  @override
  ConsumerState<Sidebar> createState() => _SidebarState();
}

class _SidebarState extends ConsumerState<Sidebar> {
  bool _suppressBlur = false;
  Timer? _blurTimer;

  @override
  void dispose() {
    _blurTimer?.cancel();
    super.dispose();
  }

  void _onCollapseToggled() {
    setState(() => _suppressBlur = true);
    _blurTimer?.cancel();
    _blurTimer = Timer(const Duration(milliseconds: 300), () {
      if (mounted) setState(() => _suppressBlur = false);
    });
  }

  Widget _frostedGlass({required bool suppressBlur, required Widget child}) {
    return BackdropFilter(
      enabled: !suppressBlur,
      filter: ImageFilter.blur(
        sigmaX: _kSidebarBlurSigma,
        sigmaY: _kSidebarBlurSigma,
      ),
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    ref.listen<bool>(sidebarCollapsedProvider, (prev, next) {
      if (prev != next) _onCollapseToggled();
    });
    final theme = Theme.of(context);
    final tokens = context.appTokens;
    final hasBackdrop = ref.watch(
      shellBackdropProvider.select((s) => s != null),
    );
    final immersive = widget.immersiveRoute && hasBackdrop;
    final isDark = theme.brightness == Brightness.dark;
    final palette = immersive
        ? _SidebarPalette.dark
        : (isDark ? _SidebarPalette.darkSurface : _SidebarPalette.light);
    final collapsed = ref.watch(sidebarCollapsedProvider);
    final sessionState = ref.watch(sessionProvider);
    final servers = ref.watch(serverListProvider).value ?? const [];
    final serverById = {for (final s in servers) s.id: s};
    final iconUrlByServer = {for (final s in servers) s.id: s.iconUrl};
    final currentIndex = widget.selectedBranchIndex;
    final locationSegments = Uri.parse(widget.location).pathSegments;
    final activeModuleId =
        locationSegments.length > 1 && locationSegments.first == 'modules'
        ? locationSegments[1]
        : null;
    final sessionByServerId = {
      for (final session in sessionState.value?.sessions ?? const [])
        session.serverId: session,
    };
    final sessionList = [
      for (final server in servers)
        if (!server.paused && sessionByServerId[server.id] != null)
          sessionByServerId[server.id]!,
    ];
    final tmdbConfigured =
        ref.watch(tmdbSettingsProvider).value?.canRequest ?? false;
    final traktConnected =
        ref.watch(traktSettingsProvider).value?.isConnected ?? false;
    final smAccountLoggedIn =
        ref.watch(smAccountProvider).value?.loggedIn ?? false;
    final enabledScriptWidgets =
        (ref.watch(installedScriptWidgetsProvider).value ?? const [])
            .where((installedWidget) => installedWidget.enabled)
            .toList(growable: false);
    final width = collapsed
        ? tokens.siderWidthCollapsed
        : tokens.siderWidthExpanded;

    return RepaintBoundary(
      child: AnimatedContainer(
        duration: tokens.siderTransition,
        curve: Curves.easeOutCubic,
        width: width,
        child: ClipRect(
          child: _frostedGlass(
            suppressBlur: _suppressBlur,
            child: AnimatedContainer(
              duration: const Duration(milliseconds: 350),
              curve: Curves.easeOut,
              decoration: BoxDecoration(
                color: palette.glassTint,
                border: Border(
                  right: BorderSide(color: palette.hairline, width: 1),
                ),
              ),
              child: OverflowBox(
                alignment: Alignment.topLeft,
                minWidth: width,
                maxWidth: width,
                child: SizedBox(
                  width: width,
                  child: Padding(
                    padding: EdgeInsets.fromLTRB(
                      collapsed ? 8 : 16,
                      10,
                      collapsed ? 8 : 16,
                      10,
                    ),
                    child: LayoutBuilder(
                      builder: (context, constraints) {
                        final effectiveCollapsed = constraints.maxWidth < 100;
                        const settingsNavReserveHeight = 48.0;
                        final reservedBottomHeight =
                            (sessionList.isNotEmpty ||
                                    enabledScriptWidgets.isNotEmpty
                                ? 16.0
                                : 0.0) +
                            4.0 +
                            settingsNavReserveHeight;
                        final availableHeaderHeight =
                            constraints.maxHeight - reservedBottomHeight;
                        final maxHeaderHeight = constraints.maxHeight.isFinite
                            ? (availableHeaderHeight < 0
                                  ? 0.0
                                  : availableHeaderHeight)
                            : double.infinity;
                        return Column(
                          crossAxisAlignment: effectiveCollapsed
                              ? CrossAxisAlignment.center
                              : CrossAxisAlignment.start,
                          children: [
                            ConstrainedBox(
                              constraints: BoxConstraints(
                                maxHeight: maxHeaderHeight,
                              ),
                              child: SingleChildScrollView(
                                child: AnimatedSize(
                                  duration: const Duration(milliseconds: 200),
                                  curve: Curves.easeOutCubic,
                                  alignment: Alignment.topCenter,
                                  child: Column(
                                    mainAxisSize: MainAxisSize.min,
                                    crossAxisAlignment: effectiveCollapsed
                                        ? CrossAxisAlignment.center
                                        : CrossAxisAlignment.start,
                                    children: [
                                      _SidebarHeader(
                                        collapsed: effectiveCollapsed,
                                        palette: palette,
                                        onToggle: () {
                                          final next = !collapsed;
                                          ref
                                                  .read(
                                                    sidebarCollapsedProvider
                                                        .notifier,
                                                  )
                                                  .state =
                                              next;
                                          _persistSidebarState(next);
                                        },
                                      ),
                                      const SizedBox(height: 16),
                                      _buildSearchEntry(
                                        context,
                                        collapsed: effectiveCollapsed,
                                        palette: palette,
                                      ),
                                      const SizedBox(height: 12),
                                      _navItem(
                                        context,
                                        icon: Icons.dns_outlined,
                                        label: '服务器',
                                        selected: currentIndex == 1,
                                        collapsed: effectiveCollapsed,
                                        palette: palette,
                                        onTap: () => widget.onNavigateBranch(1),
                                      ),
                                      _navItem(
                                        context,
                                        icon: Icons.dashboard_outlined,
                                        label: '聚合视界',
                                        selected: currentIndex == 2,
                                        collapsed: effectiveCollapsed,
                                        palette: palette,
                                        onTap: () => widget.onNavigateBranch(2),
                                      ),
                                      if (tmdbConfigured)
                                        _navItem(
                                          context,
                                          icon: Icons.explore_outlined,
                                          label: '发现',
                                          selected: currentIndex == 3,
                                          collapsed: effectiveCollapsed,
                                          palette: palette,
                                          onTap: () =>
                                              widget.onNavigateBranch(3),
                                        ),
                                      if (smAccountLoggedIn && traktConnected)
                                        _navItem(
                                          context,
                                          icon: Icons.calendar_today_outlined,
                                          label: '日历',
                                          selected: currentIndex == 4,
                                          collapsed: effectiveCollapsed,
                                          palette: palette,
                                          onTap: () =>
                                              widget.onNavigateBranch(4),
                                        ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                            if (sessionList.isNotEmpty ||
                                enabledScriptWidgets.isNotEmpty) ...[
                              const SizedBox(height: 16),
                              Expanded(
                                child: SingleChildScrollView(
                                  child: Column(
                                    children: [
                                      ...sessionList.map(
                                        (session) => Padding(
                                          padding: const EdgeInsets.only(
                                            bottom: 4,
                                          ),
                                          child: Builder(
                                            builder: (context) {
                                              final server =
                                                  serverById[session.serverId];
                                              final actions =
                                                  buildServerActionCallbacks(
                                                    context: context,
                                                    ref: ref,
                                                    server: server,
                                                    session: session,
                                                  );
                                              return ServerMenuItem(
                                                serverName: session.serverName,
                                                iconUrl:
                                                    iconUrlByServer[session
                                                        .serverId] ??
                                                    '',
                                                isActive:
                                                    session.isActive &&
                                                    activeModuleId == null,
                                                collapsed: effectiveCollapsed,
                                                foregroundActive: palette.fg,
                                                foregroundInactive:
                                                    palette.fgMuted,
                                                onTap: () async {
                                                  if (!session.isActive) {
                                                    await ref
                                                        .read(
                                                          sessionProvider
                                                              .notifier,
                                                        )
                                                        .switchSession(
                                                          session.serverId,
                                                        );
                                                    widget.onNavigateBranch(
                                                      0,
                                                      initialLocation: true,
                                                    );
                                                    return;
                                                  }
                                                  if (widget.location == '/') {
                                                    await Future.wait([
                                                      ref
                                                          .read(
                                                            libraryOverviewProvider
                                                                .notifier,
                                                          )
                                                          .softRefresh(),
                                                      ref
                                                          .read(
                                                            homeBannerProvider
                                                                .notifier,
                                                          )
                                                          .softRefresh(),
                                                    ]);
                                                  } else {
                                                    widget.onNavigateBranch(
                                                      0,
                                                      initialLocation: true,
                                                    );
                                                  }
                                                },
                                                onChangeIcon:
                                                    actions.onChangeIcon,
                                                onEdit: actions.onEdit,
                                                onChangePassword:
                                                    actions.onChangePassword,
                                                onTogglePause:
                                                    actions.onTogglePause,
                                                onDelete: actions.onDelete,
                                              );
                                            },
                                          ),
                                        ),
                                      ),
                                      for (final installedWidget
                                          in enabledScriptWidgets)
                                        _navItem(
                                          context,
                                          icon: Icons.extension_rounded,
                                          label: installedWidget.manifest.title,
                                          selected:
                                              activeModuleId ==
                                              installedWidget.manifest.id,
                                          collapsed: effectiveCollapsed,
                                          palette: palette,


                                          onTap: () => context.go(
                                            '/modules/${Uri.encodeComponent(installedWidget.manifest.id)}',
                                          ),
                                        ),
                                    ],
                                  ),
                                ),
                              ),
                            ] else
                              const Spacer(),
                            const SizedBox(height: 4),
                            _navItem(
                              context,
                              icon: Icons.settings_outlined,
                              label: '设置',
                              selected: false,
                              collapsed: effectiveCollapsed,
                              palette: palette,
                              onTap: () => showSettingsDialog(context),
                            ),
                          ],
                        );
                      },
                    ),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildSearchEntry(
    BuildContext context, {
    required bool collapsed,
    required _SidebarPalette palette,
  }) {
    final theme = Theme.of(context);

    if (collapsed) {
      return Tooltip(
        message: '搜索',
        preferBelow: false,
        child: GestureDetector(
          onTap: () => context.push('/global-search'),
          child: MouseRegion(
            cursor: SystemMouseCursors.click,
            child: SizedBox(
              width: 44,
              height: 38,
              child: Center(
                child: Icon(
                  Icons.search_outlined,
                  size: 20,
                  color: palette.fgFaint,
                ),
              ),
            ),
          ),
        ),
      );
    }

    return GestureDetector(
      onTap: () => context.push('/global-search'),
      child: MouseRegion(
        cursor: SystemMouseCursors.click,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 6),
          child: Row(
            children: [
              Icon(Icons.search_outlined, size: 18, color: palette.fgMuted),
              const SizedBox(width: 10),
              Expanded(
                child: Text(
                  '搜索',
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: palette.fgMuted,
                  ),
                ),
              ),
              Text(
                '⌘K',
                style: theme.textTheme.labelSmall?.copyWith(
                  color: palette.fgFaint,
                  fontSize: 10,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _navItem(
    BuildContext context, {
    required IconData icon,
    required String label,
    required bool selected,
    required bool collapsed,
    required _SidebarPalette palette,
    required VoidCallback onTap,
  }) {
    final theme = Theme.of(context);
    final foreground = selected ? palette.fg : palette.fgMuted;

    final child = GestureDetector(
      onTap: onTap,
      child: MouseRegion(
        cursor: SystemMouseCursors.click,
        child: Padding(
          padding: EdgeInsets.symmetric(
            horizontal: collapsed ? 0 : 4,
            vertical: 8,
          ),
          child: collapsed
              ? SizedBox(
                  width: 44,
                  child: Center(child: Icon(icon, size: 20, color: foreground)),
                )
              : Row(
                  children: [
                    Container(
                      width: 2,
                      height: 16,
                      margin: const EdgeInsets.only(right: 10),
                      decoration: BoxDecoration(
                        color: selected ? palette.fg : Colors.transparent,
                        borderRadius: BorderRadius.circular(1),
                      ),
                    ),
                    Icon(icon, size: 18, color: foreground),
                    const SizedBox(width: 10),
                    Expanded(
                      child: Text(
                        label,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: theme.textTheme.bodyMedium?.copyWith(
                          color: foreground,
                          fontWeight: selected
                              ? FontWeight.w600
                              : FontWeight.w400,
                        ),
                      ),
                    ),
                  ],
                ),
        ),
      ),
    );

    if (collapsed) {
      return Tooltip(
        message: label,
        preferBelow: false,
        child: Padding(padding: const EdgeInsets.only(bottom: 2), child: child),
      );
    }

    return Padding(padding: const EdgeInsets.only(bottom: 2), child: child);
  }
}

class _SidebarHeader extends StatelessWidget {
  final bool collapsed;
  final _SidebarPalette palette;
  final VoidCallback onToggle;

  const _SidebarHeader({
    required this.collapsed,
    required this.palette,
    required this.onToggle,
  });

  @override
  Widget build(BuildContext context) {
    final tokens = context.appTokens;

    if (collapsed) {
      return Column(
        children: [
          TopDragArea(
            child: SizedBox(
              width: double.infinity,
              height: tokens.titleBarHeight,
            ),
          ),
          const SizedBox(height: 4),
          GestureDetector(
            onTap: onToggle,
            child: MouseRegion(
              cursor: SystemMouseCursors.click,
              child: Icon(Icons.menu, size: 18, color: palette.fgFaint),
            ),
          ),
        ],
      );
    }

    return TopDragArea(
      child: SizedBox(
        height: tokens.titleBarHeight,
        child: Row(
          children: [
            const Spacer(),
            GestureDetector(
              onTap: onToggle,
              child: MouseRegion(
                cursor: SystemMouseCursors.click,
                child: Padding(
                  padding: const EdgeInsets.all(4),
                  child: Icon(Icons.menu, size: 18, color: palette.fgFaint),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
