import 'package:flutter/material.dart'; import '../../../../l10n/app_localizations.dart'; import '../../../../core/logging/logger.dart'; import '../../../../shared/theme/design_tokens.dart'; import '../../../../shared/widgets/app_modal_dialog.dart'; import '../../../../shared/widgets/gua_icon.dart'; import '../../../../shared/widgets/toast/toast.dart'; import '../../../../shared/widgets/toast/toast_type.dart'; import '../../data/models/profile_settings.dart'; import '../widgets/settings_section_widgets.dart'; import 'coin_center_screen.dart'; import 'general_settings_screen.dart'; import 'legal_center_screen.dart'; import 'profile_edit_screen.dart'; class SettingsScreen extends StatefulWidget { const SettingsScreen({ super.key, required this.account, required this.settings, required this.coinBalance, required this.onInterfaceLanguageChanged, required this.onSettingsChanged, required this.onUploadAvatar, required this.onLogout, }); final String account; final ProfileSettingsV1 settings; final int coinBalance; final Future Function(String languageTag) onInterfaceLanguageChanged; final Future Function(ProfileSettingsV1 settings) onSettingsChanged; final Future Function(String filePath) onUploadAvatar; final Future Function() onLogout; @override State createState() => _SettingsScreenState(); } class _SettingsScreenState extends State { final Logger _logger = getLogger('features.settings.settings_screen'); late ProfileSettingsV1 _settings; @override void initState() { super.initState(); _settings = widget.settings; } @override void didUpdateWidget(covariant SettingsScreen oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.settings != widget.settings) { _settings = widget.settings; } } @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.settingsTitle), centerTitle: true, backgroundColor: colors.surfaceContainerLow, surfaceTintColor: colors.surfaceContainerLow, ), body: ListView( padding: const EdgeInsets.fromLTRB( AppSpacing.lg, AppSpacing.md, AppSpacing.lg, AppSpacing.xl, ), children: [ ProfileHeaderCard( account: widget.account, displayName: _settings.displayName.isEmpty ? widget.account : _settings.displayName, bio: _settings.bio, avatarUrl: _settings.avatarUrl, onEditTap: _openProfileEdit, ), const SizedBox(height: AppSpacing.lg), WalletHeroCard( balance: widget.coinBalance, subtitle: l10n.settingsCoinHeroSubtitle, onTap: _openCoinCenter, ), const SizedBox(height: AppSpacing.xl), SettingsGroupCard( children: [ SettingsMenuTile( icon: Icons.tune_rounded, title: l10n.settingsGeneralTitle, tint: colors.primary, background: colors.surfaceContainerHighest, onTap: _openGeneralSettings, ), SettingsMenuTile( icon: Icons.description_outlined, title: l10n.settingsLegalCenterTitle, tint: colors.secondary, background: colors.surfaceContainerHighest, showDivider: false, onTap: _openLegalCenter, ), ], ), const SizedBox(height: AppSpacing.xl), FilledButton( onPressed: _confirmLogout, style: FilledButton.styleFrom( elevation: 0, backgroundColor: colors.error, foregroundColor: colors.onError, padding: const EdgeInsets.symmetric(vertical: AppSpacing.lg), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.full), ), ), child: Text(l10n.logout), ), ], ), ); } Future _openCoinCenter() async { await Navigator.of(context).push( MaterialPageRoute( builder: (_) => CoinCenterScreen(balance: widget.coinBalance), ), ); } Future _openGeneralSettings() async { final result = await Navigator.of(context).push( MaterialPageRoute( builder: (_) => GeneralSettingsScreen( settings: _settings, onInterfaceLanguageChanged: widget.onInterfaceLanguageChanged, ), ), ); if (result == null || !mounted) { return; } setState(() { _settings = result; }); } Future _openProfileEdit() async { final result = await Navigator.of(context).push( MaterialPageRoute( builder: (_) => ProfileEditScreen( account: widget.account, settings: _settings, onUploadAvatar: widget.onUploadAvatar, ), ), ); if (result == null || !mounted) { return; } try { await widget.onSettingsChanged(result); if (!mounted) { return; } setState(() { _settings = result; }); } catch (error, stackTrace) { _logger.error( message: 'Failed to save profile settings', error: error, stackTrace: stackTrace, ); if (!mounted) { return; } Toast.show( context, AppLocalizations.of(context)!.errorRequestGeneric, type: ToastType.error, ); } } Future _openLegalCenter() async { await Navigator.of(context).push( MaterialPageRoute(builder: (_) => const LegalCenterScreen()), ); } Future _confirmLogout() async { final l10n = AppLocalizations.of(context)!; final confirmed = await showDialog( context: context, builder: (dialogContext) { return AppModalDialog( title: l10n.settingsLogoutDialogTitle, message: l10n.settingsLogoutDialogBody, iconWidget: const GuaIcon(), actions: [ AppModalDialogAction( label: l10n.settingsCancel, onPressed: () => Navigator.of(dialogContext).pop(false), ), AppModalDialogAction( label: l10n.logout, primary: true, destructive: true, onPressed: () => Navigator.of(dialogContext).pop(true), ), ], ); }, ); if (confirmed != true) { return; } await widget.onLogout(); if (!mounted) { return; } Navigator.of(context).popUntil((route) => route.isFirst); } }