import 'dart:async';
import 'dart:math' as math;

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

import '../../providers/server_provider.dart';
import '../../providers/server_sync_provider.dart';
import '../../providers/sm_account_provider.dart';
import '../../shared/constants/breakpoints.dart';
import '../../shared/theme/app_theme.dart';
import '../../shared/theme/app_theme_scope.dart';
import '../../shared/widgets/app_card.dart';
import '../../shared/widgets/app_dialog.dart';
import '../../shared/widgets/app_inline_alert.dart';
import '../../shared/widgets/app_sliver_header.dart';
import '../../shared/widgets/app_loading_ring.dart';
import '../../shared/widgets/app_snack_bar.dart';
import '../../shared/widgets/page_background.dart';
import 'account_auth_page.dart';

typedef AccountFeedback = void Function(String message, {AppAlertTone tone});

Future<String?> showAccountCenterSheet(BuildContext context) {
  final isCompact = Breakpoints.isCompact(MediaQuery.sizeOf(context).width);
  if (isCompact) return _showAccountBottomSheet(context);
  return _showAccountSideSheet(context);
}

Future<String?> _showAccountBottomSheet(BuildContext context) {
  return showModalBottomSheet<String>(
    context: context,
    useRootNavigator: true,
    isScrollControlled: true,
    useSafeArea: true,
    isDismissible: true,
    backgroundColor: Colors.transparent,
    barrierColor: Colors.black38,
    builder: (_) => const AppThemeScope(child: _AccountBottomSheet()),
  );
}

Future<String?> _showAccountSideSheet(BuildContext context) {
  return showGeneralDialog<String>(
    context: context,
    useRootNavigator: true,
    barrierDismissible: true,
    barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
    barrierColor: Colors.black38,
    transitionDuration: const Duration(milliseconds: 220),
    pageBuilder: (_, _, _) => const AppThemeScope(child: _AccountSideSheet()),
    transitionBuilder: (_, animation, _, child) {
      final curved = CurvedAnimation(
        parent: animation,
        curve: Curves.easeOutCubic,
        reverseCurve: Curves.easeInCubic,
      );
      return SlideTransition(
        position: Tween<Offset>(
          begin: const Offset(1, 0),
          end: Offset.zero,
        ).animate(curved),
        child: child,
      );
    },
  );
}


class AccountCenterPage extends ConsumerStatefulWidget {
  const AccountCenterPage({super.key});

  @override
  ConsumerState<AccountCenterPage> createState() => _AccountCenterPageState();
}

class _AccountCenterPageState extends ConsumerState<AccountCenterPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      extendBodyBehindAppBar: true,
      body: Stack(
        children: [
          const Positioned.fill(child: PageBackground()),
          CustomScrollView(
            physics: const AlwaysScrollableScrollPhysics(
              parent: BouncingScrollPhysics(),
            ),
            slivers: [
              AppSliverHeader(
                title: '账号',
                leading: IconButton(
                  icon: const Icon(Icons.arrow_back_rounded),
                  onPressed: () => context.pop(),
                ),
              ),
              SliverPadding(
                padding: const EdgeInsets.fromLTRB(16, 12, 16, 100),
                sliver: SliverToBoxAdapter(
                  child: AccountCenterContent(
                    onAuthRequested: _openAuth,
                    onFeedback: _pageFeedback,
                    syncConfirmInPopover: false,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Future<void> _openAuth() async {
    final message = await context.push<String>('/account/auth');
    if (!mounted || message == null || message.isEmpty) return;
    showAppSnackBar(context, message, tone: AppSnackTone.success);
  }

  void _pageFeedback(String message, {AppAlertTone tone = AppAlertTone.info}) {
    showAppSnackBar(
      context,
      message,
      tone: switch (tone) {
        AppAlertTone.error => AppSnackTone.error,
        AppAlertTone.warning => AppSnackTone.warning,
        AppAlertTone.success => AppSnackTone.success,
        AppAlertTone.info => AppSnackTone.neutral,
      },
    );
  }
}

class AccountCenterContent extends ConsumerStatefulWidget {
  final VoidCallback onAuthRequested;
  final AccountFeedback onFeedback;
  final bool syncConfirmInPopover;

  const AccountCenterContent({
    super.key,
    required this.onAuthRequested,
    required this.onFeedback,
    required this.syncConfirmInPopover,
  });

  @override
  ConsumerState<AccountCenterContent> createState() =>
      _AccountCenterContentState();
}

class _AccountCenterContentState extends ConsumerState<AccountCenterContent> {
  bool _logoutBusy = false;

  @override
  Widget build(BuildContext context) {
    final account = ref.watch(smAccountProvider).value;
    final syncState = ref.watch(serverSyncProvider);
    final status = account?.status ?? SmAuthStatus.unauthenticated;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _buildAccountSection(context, account, status),
        const SizedBox(height: 24),
        _buildSyncSection(context, account, syncState),
      ],
    );
  }

  Widget _buildAccountSection(
    BuildContext context,
    SmAccountState? account,
    SmAuthStatus status,
  ) {
    return switch (status) {
      SmAuthStatus.authenticated => _buildLoggedIn(context, account!),
      SmAuthStatus.restoring => _buildRestoring(context, account!),
      SmAuthStatus.expired => _buildReauth(
        context,
        account!,
        title: '登录已过期',
        subtitle: '请重新登录以继续使用扩展服务',
      ),
      SmAuthStatus.degraded => _buildReauth(
        context,
        account!,
        title: '账号凭据不完整',
        subtitle: '请重新登录以继续使用扩展服务',
      ),
      SmAuthStatus.unauthenticated => _buildEntry(context),
    };
  }

  Widget _buildEntry(BuildContext context) {
    final theme = Theme.of(context);
    return AppCard(
      onTap: widget.onAuthRequested,
      padding: const EdgeInsets.all(20),
      child: Row(
        children: [
          Container(
            width: 48,
            height: 48,
            decoration: BoxDecoration(
              color: theme.colorScheme.onSurface.withValues(alpha: 0.08),
              shape: BoxShape.circle,
            ),
            child: Icon(
              Icons.person_outline_rounded,
              size: 24,
              color: theme.colorScheme.onSurface.withValues(alpha: 0.4),
            ),
          ),
          const SizedBox(width: 14),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '登录 Player 账号',
                  style: theme.textTheme.titleSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                    fontSize: 16,
                  ),
                ),
                const SizedBox(height: 3),
                Text(
                  '登录以使用云同步和 TMDB 等扩展服务',
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: theme.colorScheme.onSurface.withValues(alpha: 0.58),
                  ),
                ),
              ],
            ),
          ),
          const Icon(Icons.chevron_right_rounded),
        ],
      ),
    );
  }

  Widget _buildRestoring(BuildContext context, SmAccountState s) {
    final theme = Theme.of(context);
    return AppCard(
      padding: const EdgeInsets.all(20),
      child: Row(
        children: [
          Container(
            width: 48,
            height: 48,
            decoration: BoxDecoration(
              color: theme.colorScheme.primary.withValues(alpha: 0.12),
              shape: BoxShape.circle,
            ),
            child: Icon(
              Icons.person_rounded,
              size: 24,
              color: theme.colorScheme.primary,
            ),
          ),
          const SizedBox(width: 14),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  s.email.isEmpty ? 'Player 账号' : s.email,
                  style: theme.textTheme.titleSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                    fontSize: 16,
                  ),
                ),
                const SizedBox(height: 3),
                Text(
                  '正在恢复登录…',
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: theme.colorScheme.onSurface.withValues(alpha: 0.58),
                  ),
                ),
              ],
            ),
          ),
          const AppLoadingRing(size: 18),
        ],
      ),
    );
  }

  Widget _buildReauth(
    BuildContext context,
    SmAccountState s, {
    required String title,
    required String subtitle,
  }) {
    final theme = Theme.of(context);
    return AppCard(
      onTap: widget.onAuthRequested,
      padding: const EdgeInsets.all(20),
      child: Row(
        children: [
          Container(
            width: 48,
            height: 48,
            decoration: BoxDecoration(
              color: const Color(0xFFFAAD14).withValues(alpha: 0.15),
              shape: BoxShape.circle,
            ),
            child: const Icon(
              Icons.error_outline,
              size: 24,
              color: Color(0xFFFAAD14),
            ),
          ),
          const SizedBox(width: 14),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  title,
                  style: theme.textTheme.titleSmall?.copyWith(
                    fontWeight: FontWeight.w700,
                    fontSize: 16,
                  ),
                ),
                const SizedBox(height: 3),
                Text(
                  subtitle,
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: theme.colorScheme.onSurface.withValues(alpha: 0.58),
                  ),
                ),
              ],
            ),
          ),
          const Icon(Icons.chevron_right_rounded),
        ],
      ),
    );
  }

  Widget _buildLoggedIn(BuildContext context, SmAccountState s) {
    final theme = Theme.of(context);
    return AppCard(
      padding: const EdgeInsets.all(20),
      child: Column(
        children: [
          Row(
            children: [
              Container(
                width: 56,
                height: 56,
                decoration: BoxDecoration(
                  color: s.isVip
                      ? const Color(0xFFFAAD14).withValues(alpha: 0.15)
                      : theme.colorScheme.primary.withValues(alpha: 0.12),
                  shape: BoxShape.circle,
                  border: s.isVip
                      ? Border.all(
                          color: const Color(0xFFFAAD14).withValues(alpha: 0.4),
                          width: 1.5,
                        )
                      : null,
                ),
                child: Icon(
                  s.isVip
                      ? Icons.workspace_premium_rounded
                      : Icons.person_rounded,
                  size: 28,
                  color: s.isVip
                      ? const Color(0xFFFAAD14)
                      : theme.colorScheme.primary,
                ),
              ),
              const SizedBox(width: 14),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      s.email.isNotEmpty ? s.email : 'Player 账号',
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: theme.textTheme.titleSmall?.copyWith(
                        fontWeight: FontWeight.w700,
                        fontSize: 17,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      _vipLabel(s),
                      style: theme.textTheme.bodySmall?.copyWith(
                        color: theme.colorScheme.onSurface.withValues(
                          alpha: 0.58,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              if (s.isVip)
                Container(
                  margin: const EdgeInsets.only(right: 8),
                  padding: const EdgeInsets.symmetric(
                    horizontal: 8,
                    vertical: 2,
                  ),
                  decoration: BoxDecoration(
                    color: const Color(0xFFFAAD14),
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: const Text(
                    'VIP',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 11,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
            ],
          ),
          const Divider(height: 32),
          InkWell(
            onTap: _logoutBusy ? null : _logout,
            child: Row(
              children: [
                Icon(
                  Icons.logout,
                  size: 18,
                  color: theme.colorScheme.onSurface.withValues(alpha: 0.6),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Text(
                    '退出登录',
                    style: theme.textTheme.bodyMedium?.copyWith(
                      color: theme.colorScheme.onSurface.withValues(alpha: 0.7),
                    ),
                  ),
                ),
                if (_logoutBusy) const AppLoadingRing(size: 18),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSyncSection(
    BuildContext context,
    SmAccountState? account,
    ServerSyncState syncState,
  ) {
    final theme = Theme.of(context);
    final hasVip = account?.hasVip ?? false;
    final busy = syncState.busy;
    final localCount = ref.watch(serverListProvider).value?.length ?? 0;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(4, 0, 4, 8),
          child: Text(
            '云同步',
            style: theme.textTheme.labelLarge?.copyWith(
              color: theme.colorScheme.onSurface.withValues(alpha: 0.55),
              fontWeight: FontWeight.w600,
            ),
          ),
        ),
        AppCard(
          padding: EdgeInsets.zero,
          child: Column(
            children: [
              _buildSyncStatus(context, syncState, hasVip),
              _divider(context),
              _SyncActionRow(
                icon: Icons.cloud_upload_outlined,
                label: '上传到云端',
                enabled: !busy && hasVip,
                busy: busy,
                usePopover: widget.syncConfirmInPopover,
                confirmTitle: '上传到云端？',
                confirmMessage: '这将把本地 $localCount 个服务器及对应登录态整包上传到云端，覆盖云端已有备份。',
                confirmLabel: '确认上传',
                onConfirm: () => _cloudUpload(localCount),
              ),
              _divider(context),
              _SyncActionRow(
                icon: Icons.cloud_download_outlined,
                label: '从云端拉取',
                enabled: !busy && hasVip,
                busy: busy,
                usePopover: widget.syncConfirmInPopover,
                destructive: true,
                confirmTitle: '从云端拉取？',
                confirmMessage:
                    '这将用云端备份整包替换本地当前的 $localCount 个服务器及对应登录态；弹幕源按 URL 合并（云端为权威）。本地未上传到云端的改动会丢失。',
                confirmLabel: '替换并拉取',
                onConfirm: () => _cloudPull(localCount),
              ),
            ],
          ),
        ),
        if (!hasVip)
          Padding(
            padding: const EdgeInsets.fromLTRB(4, 8, 4, 0),
            child: Text(
              '云同步需要 VIP 会员',
              style: theme.textTheme.bodySmall?.copyWith(
                color: theme.colorScheme.onSurface.withValues(alpha: 0.45),
              ),
            ),
          ),
      ],
    );
  }

  Widget _buildSyncStatus(
    BuildContext context,
    ServerSyncState syncState,
    bool hasVip,
  ) {
    final theme = Theme.of(context);
    String statusText;
    Color? statusColor;

    if (syncState.lastSyncError != null) {
      statusText = '同步失败';
      statusColor = const Color(0xFFEF4444);
    } else if (syncState.lastSyncAt != null) {
      statusText = '上次同步：${_formatTime(syncState.lastSyncAt!)}';
      statusColor = null;
    } else if (!hasVip) {
      statusText = '未启用';
      statusColor = null;
    } else {
      statusText = '未同步';
      statusColor = null;
    }

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13),
      child: Row(
        children: [
          Icon(
            syncState.lastSyncError != null
                ? Icons.error_outline
                : Icons.cloud_done_outlined,
            size: 20,
            color:
                statusColor ??
                theme.colorScheme.onSurface.withValues(alpha: 0.5),
          ),
          const SizedBox(width: 14),
          Text(
            statusText,
            style: theme.textTheme.bodyMedium?.copyWith(
              color:
                  statusColor ??
                  theme.colorScheme.onSurface.withValues(alpha: 0.6),
            ),
          ),
        ],
      ),
    );
  }

  Widget _divider(BuildContext context) {
    return Divider(
      height: 1,
      indent: 50,
      color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.08),
    );
  }

  String _vipLabel(SmAccountState s) {
    if (s.vipPermanent) return '永久 VIP';
    if (s.isVip && s.vipExpiresAt != null) {
      final d = DateTime.fromMillisecondsSinceEpoch(s.vipExpiresAt!);
      String two(int v) => v.toString().padLeft(2, '0');
      return 'VIP 有效期至 ${d.year}-${two(d.month)}-${two(d.day)}';
    }
    return '已登录';
  }

  String _formatTime(DateTime t) {
    String two(int v) => v.toString().padLeft(2, '0');
    final now = DateTime.now();
    if (t.year == now.year && t.month == now.month && t.day == now.day) {
      return '今天 ${two(t.hour)}:${two(t.minute)}';
    }
    return '${t.month}/${t.day} ${two(t.hour)}:${two(t.minute)}';
  }

  Future<void> _logout() async {
    setState(() => _logoutBusy = true);
    await ref.read(smAccountProvider.notifier).logout();
    if (!mounted) return;
    setState(() => _logoutBusy = false);
    widget.onFeedback('已退出登录', tone: AppAlertTone.success);
  }

  Future<void> _cloudUpload(int localCount) async {
    if (!widget.syncConfirmInPopover) {
      final confirmed = await showAppConfirmDialog(
        context,
        title: '上传到云端',
        body: Text('这将把本地 $localCount 个服务器及对应登录态整包上传到云端，覆盖云端已有的备份。确定继续？'),
        confirmLabel: '上传',
      );
      if (!confirmed || !mounted) return;
    }

    final outcome = await ref.read(serverSyncProvider.notifier).upload();
    if (!mounted) return;
    widget.onFeedback(
      outcome.message,
      tone: outcome.isError ? AppAlertTone.error : AppAlertTone.info,
    );
  }

  Future<void> _cloudPull(int localCount) async {
    if (!widget.syncConfirmInPopover) {
      final confirmed = await showAppConfirmDialog(
        context,
        title: '从云端拉取',
        body: Text(
          '这将用云端备份整包替换本地当前的 $localCount 个服务器及对应登录态；'
          '弹幕源按 URL 合并（云端为权威）。'
          '本地未上传到云端的改动会丢失。确定继续？',
        ),
        confirmLabel: '替换并拉取',
        destructive: true,
      );
      if (!confirmed || !mounted) return;
    }

    final outcome = await ref.read(serverSyncProvider.notifier).pull();
    if (!mounted) return;
    widget.onFeedback(
      outcome.message,
      tone: outcome.isError ? AppAlertTone.error : AppAlertTone.info,
    );
  }
}

class _SyncActionRow extends StatelessWidget {
  final IconData icon;
  final String label;
  final bool enabled;
  final bool busy;
  final bool usePopover;
  final String confirmTitle;
  final String confirmMessage;
  final String confirmLabel;
  final bool destructive;
  final Future<void> Function() onConfirm;

  const _SyncActionRow({
    required this.icon,
    required this.label,
    required this.enabled,
    required this.busy,
    required this.usePopover,
    required this.confirmTitle,
    required this.confirmMessage,
    required this.confirmLabel,
    required this.onConfirm,
    this.destructive = false,
  });

  @override
  Widget build(BuildContext context) {
    final child = _SyncActionRowContent(
      icon: icon,
      label: label,
      enabled: enabled,
      busy: busy,
    );

    if (!usePopover) {
      return InkWell(
        onTap: enabled ? () => unawaited(onConfirm()) : null,
        child: child,
      );
    }

    return FPopover(
      constraints: const FPortalConstraints(maxWidth: 300),
      popoverAnchor: Alignment.topRight,
      childAnchor: Alignment.bottomRight,
      popoverBuilder: (_, controller) => _SyncConfirmBubble(
        title: confirmTitle,
        message: confirmMessage,
        confirmLabel: confirmLabel,
        destructive: destructive,
        onCancel: () => unawaited(controller.hide()),
        onConfirm: () {
          unawaited(controller.hide());
          unawaited(onConfirm());
        },
      ),
      builder: (_, controller, child) =>
          InkWell(onTap: enabled ? controller.toggle : null, child: child),
      child: child,
    );
  }
}

class _SyncActionRowContent extends StatelessWidget {
  final IconData icon;
  final String label;
  final bool enabled;
  final bool busy;

  const _SyncActionRowContent({
    required this.icon,
    required this.label,
    required this.enabled,
    required this.busy,
  });

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13),
      child: Row(
        children: [
          Icon(
            icon,
            size: 20,
            color: enabled
                ? theme.colorScheme.primary
                : theme.colorScheme.onSurface.withValues(alpha: 0.3),
          ),
          const SizedBox(width: 14),
          Expanded(
            child: Text(
              label,
              style: theme.textTheme.bodyMedium?.copyWith(
                color: enabled
                    ? null
                    : theme.colorScheme.onSurface.withValues(alpha: 0.4),
              ),
            ),
          ),
          if (busy) const AppLoadingRing(size: 18),
        ],
      ),
    );
  }
}

class _SyncConfirmBubble extends StatelessWidget {
  final String title;
  final String message;
  final String confirmLabel;
  final bool destructive;
  final VoidCallback onCancel;
  final VoidCallback onConfirm;

  const _SyncConfirmBubble({
    required this.title,
    required this.message,
    required this.confirmLabel,
    required this.destructive,
    required this.onCancel,
    required this.onConfirm,
  });

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final tokens = context.appTokens;
    return SizedBox(
      width: 280,
      child: Padding(
        padding: const EdgeInsets.all(14),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              title,
              style: theme.textTheme.titleSmall?.copyWith(
                fontWeight: FontWeight.w700,
              ),
            ),
            const SizedBox(height: 6),
            Text(
              message,
              style: theme.textTheme.bodySmall?.copyWith(
                color: tokens.mutedForeground,
                height: 1.35,
              ),
            ),
            const SizedBox(height: 12),
            Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                FButton(
                  onPress: onCancel,
                  variant: FButtonVariant.outline,
                  mainAxisSize: MainAxisSize.min,
                  child: const Text('取消'),
                ),
                const SizedBox(width: 8),
                FButton(
                  onPress: onConfirm,
                  variant: destructive
                      ? FButtonVariant.destructive
                      : FButtonVariant.primary,
                  mainAxisSize: MainAxisSize.min,
                  child: Text(confirmLabel),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class _AccountSideSheet extends StatelessWidget {
  const _AccountSideSheet();

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final screenWidth = MediaQuery.sizeOf(context).width;
    final width = math.min(
      math.min(480.0, math.max(400.0, screenWidth * 0.32)),
      screenWidth * 0.92,
    );

    return Align(
      alignment: Alignment.centerRight,
      child: SizedBox(
        width: width,
        height: double.infinity,
        child: Material(
          color: theme.colorScheme.surface,
          clipBehavior: Clip.antiAlias,
          borderRadius: const BorderRadius.horizontal(
            left: Radius.circular(24),
          ),
          child: const _AccountSheetFrame(isSideSheet: true),
        ),
      ),
    );
  }
}

class _AccountBottomSheet extends StatelessWidget {
  const _AccountBottomSheet();

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final size = MediaQuery.sizeOf(context);
    final viewInsets = MediaQuery.viewInsetsOf(context);

    final sheet = Material(
      color: theme.colorScheme.surface,
      clipBehavior: Clip.antiAlias,
      borderRadius: const BorderRadius.vertical(top: Radius.circular(24)),
      child: const SafeArea(
        top: false,
        child: _AccountSheetFrame(isSideSheet: false),
      ),
    );

    return AnimatedPadding(
      duration: const Duration(milliseconds: 220),
      curve: Curves.easeOutCubic,
      padding: EdgeInsets.only(bottom: viewInsets.bottom),
      child: Align(
        alignment: Alignment.bottomCenter,
        child: ConstrainedBox(
          constraints: BoxConstraints(maxHeight: size.height * 0.92),
          child: sheet,
        ),
      ),
    );
  }
}

class _AccountSheetFrame extends StatefulWidget {
  final bool isSideSheet;

  const _AccountSheetFrame({required this.isSideSheet});

  @override
  State<_AccountSheetFrame> createState() => _AccountSheetFrameState();
}

class _AccountSheetFrameState extends State<_AccountSheetFrame> {
  bool _authMode = false;

  @override
  Widget build(BuildContext context) {
    Widget body = AnimatedSwitcher(
      duration: const Duration(milliseconds: 180),


      layoutBuilder: (currentChild, previousChildren) => Stack(
        alignment: Alignment.topCenter,
        children: [
          ...previousChildren,
          if (currentChild != null) currentChild,
        ],
      ),
      child: _authMode ? _authBody(context) : _overviewBody(context),
    );

    body = widget.isSideSheet
        ? Expanded(child: body)
        : Flexible(fit: FlexFit.loose, child: body);

    return Column(
      mainAxisSize: widget.isSideSheet ? MainAxisSize.max : MainAxisSize.min,
      children: [
        if (widget.isSideSheet)
          SizedBox(height: MediaQuery.paddingOf(context).top),
        _AccountSheetTitleBar(
          showBack: _authMode,
          isSideSheet: widget.isSideSheet,
          onBack: () => setState(() => _authMode = false),
          onClose: () => Navigator.of(context).pop(),
        ),
        Divider(
          height: 1,
          color: Theme.of(
            context,
          ).colorScheme.onSurface.withValues(alpha: 0.08),
        ),
        body,
      ],
    );
  }

  Widget _overviewBody(BuildContext context) {
    return SingleChildScrollView(
      key: const ValueKey('overview'),
      physics: const BouncingScrollPhysics(),
      padding: const EdgeInsets.fromLTRB(16, 16, 16, 24),
      child: AccountCenterContent(
        onAuthRequested: () => setState(() => _authMode = true),
        onFeedback: (message, {tone = AppAlertTone.info}) {
          showAppToast(context, message, tone: tone);
        },
        syncConfirmInPopover: true,
      ),
    );
  }

  Widget _authBody(BuildContext context) {
    return SingleChildScrollView(
      key: const ValueKey('auth'),
      physics: const BouncingScrollPhysics(),
      padding: const EdgeInsets.fromLTRB(24, 18, 24, 28),
      child: Align(
        alignment: Alignment.topCenter,
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 400),
          child: AccountAuthForm(
            onSuccess: (message) => Navigator.of(context).pop(message),
          ),
        ),
      ),
    );
  }
}

class _AccountSheetTitleBar extends StatelessWidget {
  final bool showBack;
  final bool isSideSheet;
  final VoidCallback onBack;
  final VoidCallback onClose;

  const _AccountSheetTitleBar({
    required this.showBack,
    required this.isSideSheet,
    required this.onBack,
    required this.onClose,
  });

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


    final reservedTrailing = isSideSheet
        ? MediaQuery.paddingOf(context).right
        : 0.0;

    return SizedBox(
      height: 56,
      child: Stack(
        alignment: Alignment.center,
        children: [
          Align(
            alignment: Alignment.centerLeft,
            child: Padding(
              padding: const EdgeInsets.only(left: 8),
              child: showBack
                  ? IconButton(
                      onPressed: onBack,
                      icon: const Icon(Icons.arrow_back_rounded),
                      tooltip: '返回',
                    )
                  : const SizedBox(width: 48),
            ),
          ),
          Text(
            '账号',
            style: theme.textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.w600,
            ),
          ),
          Align(
            alignment: Alignment.centerRight,
            child: Padding(
              padding: EdgeInsets.only(right: 8 + reservedTrailing),
              child: IconButton(
                onPressed: onClose,
                icon: const Icon(Icons.close_rounded),
                tooltip: '关闭',
              ),
            ),
          ),
        ],
      ),
    );
  }
}
