import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:url_launcher/url_launcher.dart'; import '../services/odoo_service.dart'; import '../services/notification_service.dart'; import '../theme/app_theme.dart'; import '../widgets/agreement_dialog.dart'; import 'login_screen.dart'; class AccountScreen extends StatefulWidget { const AccountScreen({super.key}); @override State createState() => _AccountScreenState(); } class _AccountScreenState extends State { final _phraseController = TextEditingController(); final _passwordController = TextEditingController(); bool _isLoading = false; String _aboutUsUrl = ''; String _contactUsUrl = ''; @override void initState() { super.initState(); _loadAppConfig(); } Future _loadAppConfig() async { try { final config = await OdooService.getAppConfig(); if (mounted) { setState(() { _aboutUsUrl = config['about_us_url'] ?? ''; _contactUsUrl = config['contact_us_url'] ?? ''; }); } } catch (_) {} } Future _launchUrl(String url) async { if (url.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('URL not configured yet.')), ); return; } final uri = Uri.tryParse(url); if (uri != null && await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } else { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Could not open link.')), ); } } } void _showTerms() { AgreementDialog.show(context, 'Terms & Conditions', AgreementTexts.termsAndConditions); } void _showPrivacy() { AgreementDialog.show(context, 'Privacy Policy', AgreementTexts.privacyPolicy); } void _logout() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove('odoo_session'); await prefs.remove('last_seen_notification_id'); await prefs.remove('last_device_notified_id'); await prefs.remove('read_notification_ids'); await NotificationService().clearBadge(); if (mounted) { Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); } } void _showDeleteConfirmationDialog() { _phraseController.clear(); _passwordController.clear(); showDialog( context: context, barrierDismissible: false, builder: (context) { return StatefulBuilder( builder: (context, setDialogState) { return AlertDialog( title: const Text( 'Delete Account Permanently', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold), ), content: SizedBox( width: double.maxFinite, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( 'WARNING: This is a permanent action. All your loyalty points, card tier history, and reward history will be deleted and cannot be recovered.', style: TextStyle( color: AppTheme.onSurface, fontWeight: FontWeight.bold, fontSize: 14, ), ), const SizedBox(height: 16), Text( 'To confirm, type "DELETE MY ACCOUNT" below:', style: TextStyle(color: AppTheme.onSurfaceVariant, fontSize: 13), ), const SizedBox(height: 8), TextField( controller: _phraseController, decoration: const InputDecoration(hintText: 'DELETE MY ACCOUNT'), style: const TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 16), Text( 'Enter your current password:', style: TextStyle(color: AppTheme.onSurfaceVariant, fontSize: 13), ), const SizedBox(height: 8), TextField( controller: _passwordController, obscureText: true, decoration: const InputDecoration(hintText: 'Password'), ), ], ), ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Cancel', style: TextStyle(color: AppTheme.onSurface, fontWeight: FontWeight.bold)), ), TextButton( onPressed: _isLoading ? null : () async { final phrase = _phraseController.text.trim(); final password = _passwordController.text; if (phrase != 'DELETE MY ACCOUNT') { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Verification phrase is incorrect.')), ); return; } if (password.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Please enter your password.')), ); return; } setDialogState(() => _isLoading = true); try { final service = OdooService(); final response = await service.deleteAccount(password); if (response != null && response['status'] == 'success') { final prefs = await SharedPreferences.getInstance(); await prefs.remove('odoo_session'); if (context.mounted) { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response['message'] ?? 'Account deleted.')), ); Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); } } else { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(response?['message'] ?? 'Deletion failed.')), ); } } } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: $e')), ); } } finally { setDialogState(() => _isLoading = false); } }, child: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.red), ) : const Text('Delete My Account', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)), ), ], ); }, ); }, ); } @override void dispose() { _phraseController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return SingleChildScrollView( child: Column( children: [ const SizedBox(height: 16), // ── Info Section ───────────────────────────────────────────── _SectionHeader(label: 'Info'), _MenuItem( icon: Icons.info_outline_rounded, label: 'About Us', onTap: () => _launchUrl(_aboutUsUrl), ), _MenuItem( icon: Icons.phone_rounded, label: 'Contact Us', onTap: () => _launchUrl(_contactUsUrl), ), const SizedBox(height: 8), // ── Legal Section ──────────────────────────────────────────── _SectionHeader(label: 'Legal'), _MenuItem( icon: Icons.description_outlined, label: 'Terms & Conditions', onTap: _showTerms, ), _MenuItem( icon: Icons.lock_outline_rounded, label: 'Privacy Policy', onTap: _showPrivacy, ), const SizedBox(height: 8), // ── Account Section ────────────────────────────────────────── _SectionHeader(label: 'Account'), _MenuItem( icon: Icons.logout_rounded, label: 'Log Out', onTap: _logout, ), _MenuItem( icon: Icons.delete_outline_rounded, label: 'Delete Account', labelColor: const Color(0xFFB02500), iconColor: const Color(0xFFB02500), onTap: _showDeleteConfirmationDialog, ), const SizedBox(height: 32), ], ), ); } } class _SectionHeader extends StatelessWidget { final String label; const _SectionHeader({required this.label}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(20, 12, 20, 4), child: Align( alignment: Alignment.centerLeft, child: Text( label.toUpperCase(), style: Theme.of(context).textTheme.labelLarge?.copyWith( color: AppTheme.onSurfaceVariant, letterSpacing: 1.2, fontSize: 11, ), ), ), ); } } class _MenuItem extends StatelessWidget { final IconData icon; final String label; final VoidCallback onTap; final Color? labelColor; final Color? iconColor; const _MenuItem({ required this.icon, required this.label, required this.onTap, this.labelColor, this.iconColor, }); @override Widget build(BuildContext context) { return Material( color: AppTheme.surfaceContainerLowest, child: InkWell( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: AppTheme.surfaceContainer, width: 1), ), ), child: Row( children: [ Icon(icon, size: 22, color: iconColor ?? AppTheme.onSurfaceVariant), const SizedBox(width: 16), Expanded( child: Text( label, style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: labelColor ?? AppTheme.onSurface, ), ), ), Icon(Icons.chevron_right, size: 20, color: AppTheme.outlineVariant), ], ), ), ), ); } }