import 'dart:async'; import 'package:flutter/material.dart'; import '../../../../core/logging/logger.dart'; import '../../../../core/network/api_problem.dart'; import '../../../../core/network/api_problem_mapper.dart'; import '../../../../l10n/app_localizations.dart'; import '../../../../shared/theme/design_tokens.dart'; import '../../../../shared/widgets/toast/toast.dart'; import '../../../../shared/widgets/toast/toast_type.dart'; import '../widgets/settings_section_widgets.dart'; class AccountDeleteScreen extends StatefulWidget { const AccountDeleteScreen({super.key, required this.onDeleteAccount}); final Future Function() onDeleteAccount; @override State createState() => _AccountDeleteScreenState(); } class _AccountDeleteScreenState extends State { final Logger _logger = getLogger('features.settings.account_delete'); bool _isDeleting = false; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final colors = Theme.of(context).colorScheme; return Scaffold( backgroundColor: colors.surfaceContainerLow, appBar: AppBar( title: Text(l10n.settingsAccountAndDataTitle), centerTitle: true, backgroundColor: colors.surfaceContainerLow, surfaceTintColor: colors.surfaceContainerLow, ), body: ListView( padding: const EdgeInsets.all(AppSpacing.lg), children: [ SettingsGroupCard( children: [ SettingsMenuTile( icon: Icons.delete_outline_rounded, title: l10n.settingsDeleteAccountTitle, tint: colors.error, background: colors.surfaceContainerHighest, titleColor: colors.error, showDivider: false, onTap: _isDeleting ? () {} : _confirmDelete, ), ], ), ], ), ); } Future _confirmDelete() async { final confirmed = await showDialog( context: context, builder: (dialogContext) { return const _DeleteConfirmDialog(); }, ); if (confirmed != true || !mounted) { return; } await _deleteAccount(); } Future _deleteAccount() async { if (_isDeleting) { return; } setState(() { _isDeleting = true; }); try { await widget.onDeleteAccount(); if (!mounted) { return; } Navigator.of(context).pop(true); } catch (error, stackTrace) { _logger.error( message: 'Delete account request failed', error: error, stackTrace: stackTrace, ); if (!mounted) { return; } final l10n = AppLocalizations.of(context)!; final message = error is ApiProblem ? mapApiProblemToMessage(error, l10n) : l10n.errorRequestGeneric; Toast.show(context, message, type: ToastType.error); setState(() { _isDeleting = false; }); } } } class _DeleteConfirmDialog extends StatefulWidget { const _DeleteConfirmDialog(); @override State<_DeleteConfirmDialog> createState() => _DeleteConfirmDialogState(); } class _DeleteConfirmDialogState extends State<_DeleteConfirmDialog> { static const int _coolDownSeconds = 5; int _secondsLeft = _coolDownSeconds; Timer? _timer; @override void initState() { super.initState(); _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (!mounted) { timer.cancel(); return; } if (_secondsLeft <= 1) { setState(() { _secondsLeft = 0; }); timer.cancel(); return; } setState(() { _secondsLeft -= 1; }); }); } @override void dispose() { _timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final colors = Theme.of(context).colorScheme; return Dialog( insetPadding: const EdgeInsets.symmetric( horizontal: AppSpacing.lg, vertical: AppSpacing.xl, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.xl), ), child: Container( padding: const EdgeInsets.fromLTRB( AppSpacing.lg, AppSpacing.lg, AppSpacing.lg, AppSpacing.md, ), decoration: BoxDecoration( color: colors.surface, borderRadius: BorderRadius.circular(AppRadius.xl), border: Border.all(color: colors.outlineVariant), ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 36, height: 36, decoration: BoxDecoration( color: colors.surfaceContainerHighest, borderRadius: BorderRadius.circular(AppRadius.md), ), alignment: Alignment.center, child: Icon( Icons.warning_rounded, color: colors.error, size: 22, ), ), const SizedBox(width: AppSpacing.sm), Expanded( child: Text( l10n.settingsDeleteAccountDialogTitle, style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.w700, ), ), ), ], ), const SizedBox(height: AppSpacing.md), Text( l10n.settingsDeleteAccountWarningBody, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colors.onSurfaceVariant, height: 1.45, ), ), const SizedBox(height: AppSpacing.sm), Container( width: double.infinity, padding: const EdgeInsets.all(AppSpacing.md), decoration: BoxDecoration( color: colors.errorContainer, borderRadius: BorderRadius.circular(AppRadius.md), border: Border.all(color: colors.error.withValues(alpha: 0.35)), ), child: Text( l10n.settingsDeleteAccountReRegisterNotice, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colors.onErrorContainer, fontWeight: FontWeight.w700, height: 1.35, ), ), ), const SizedBox(height: AppSpacing.md), Text( _secondsLeft > 0 ? l10n.settingsDeleteAccountWaitAction(_secondsLeft) : l10n.settingsDeleteAccountDialogBody, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: colors.error, fontWeight: FontWeight.w600, ), ), const SizedBox(height: AppSpacing.lg), Row( children: [ Expanded( child: OutlinedButton( onPressed: () => Navigator.of(context).pop(false), style: OutlinedButton.styleFrom( foregroundColor: colors.onSurface, side: BorderSide(color: colors.outline), minimumSize: const Size.fromHeight(44), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.full), ), ), child: Text(l10n.settingsCancel), ), ), const SizedBox(width: AppSpacing.sm), Expanded( child: FilledButton( onPressed: _secondsLeft <= 0 ? () => Navigator.of(context).pop(true) : null, style: FilledButton.styleFrom( backgroundColor: colors.error, foregroundColor: colors.onError, disabledBackgroundColor: colors.error.withValues( alpha: 0.4, ), disabledForegroundColor: colors.onError.withValues( alpha: 0.8, ), minimumSize: const Size.fromHeight(44), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.full), ), ), child: Text(l10n.settingsDeleteAccountAction), ), ), ], ), ], ), ), ); } }