import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qpay/screens/accounts/account_provider.dart'; import 'package:qpay/screens/accounts/models/account_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; class AccountBalanceWidget extends StatefulWidget { final String? selectedCurrency; final ValueChanged? onCurrencySelected; const AccountBalanceWidget({ super.key, this.selectedCurrency, this.onCurrencySelected, }); @override State createState() => _AccountBalanceWidgetState(); } class _AccountBalanceWidgetState extends State { late AccountProvider _accountProvider; AccountModel? _usdAccount; AccountModel? _zwgAccount; bool _isLoadingUsd = false; bool _isLoadingZwG = false; String? _usdError; String? _zwgError; String? _phoneNumber; @override void initState() { super.initState(); _accountProvider = AccountProvider(); _loadBalances(); } @override void dispose() { _accountProvider.dispose(); super.dispose(); } Future _loadBalances() async { final prefs = await SharedPreferences.getInstance(); _phoneNumber = prefs.getString('phone'); if (_phoneNumber == null || _phoneNumber!.isEmpty) return; setState(() { _isLoadingUsd = true; _isLoadingZwG = true; }); // Fetch USD balance final usdResult = await _accountProvider.fetchAccount( 'USD$_phoneNumber', ); if (mounted) { setState(() { _isLoadingUsd = false; if (usdResult.isSuccess && usdResult.data != null) { _usdAccount = usdResult.data; _usdError = null; } else { _usdError = usdResult.error; } }); } // Fetch ZWG balance final zwgResult = await _accountProvider.fetchAccount( 'ZWG$_phoneNumber', ); if (mounted) { setState(() { _isLoadingZwG = false; if (zwgResult.isSuccess && zwgResult.data != null) { _zwgAccount = zwgResult.data; _zwgError = null; } else { _zwgError = zwgResult.error; } }); } } @override Widget build(BuildContext context) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; if (_phoneNumber == null || _phoneNumber!.isEmpty) { return const SizedBox.shrink(); } return Padding( padding: const EdgeInsets.only(bottom: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: _buildCompactCard( theme: theme, isDark: isDark, currencyCode: 'USD', flagAsset: 'united-states.png', balance: _usdAccount?.balance, isLoading: _isLoadingUsd, error: _usdError, isSelected: widget.selectedCurrency == 'USD', gradientColors: [ const Color(0xFF0D47A1), const Color(0xFF1976D2), ], ), ), const SizedBox(width: 10), Expanded( child: _buildCompactCard( theme: theme, isDark: isDark, currencyCode: 'ZWG', flagAsset: 'zimbabwe.png', balance: _zwgAccount?.balance, isLoading: _isLoadingZwG, error: _zwgError, isSelected: widget.selectedCurrency == 'ZWG', gradientColors: [ const Color(0xFF1B5E20), const Color(0xFF388E3C), ], ), ), ], ), const SizedBox(height: 6), Center( child: TextButton.icon( onPressed: _isLoadingUsd || _isLoadingZwG ? null : () { _loadBalances(); }, icon: Icon( Icons.refresh_rounded, size: 14, color: _isLoadingUsd || _isLoadingZwG ? (isDark ? Colors.white24 : Colors.grey.shade400) : theme.colorScheme.primary, ), label: Text( _isLoadingUsd || _isLoadingZwG ? 'Refreshing...' : 'Refresh', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w600, color: _isLoadingUsd || _isLoadingZwG ? (isDark ? Colors.white24 : Colors.grey.shade400) : theme.colorScheme.primary, ), ), style: TextButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), ), ), ], ), ); } Widget _buildCompactCard({ required ThemeData theme, required bool isDark, required String currencyCode, required String flagAsset, double? balance, required bool isLoading, String? error, required bool isSelected, required List gradientColors, }) { return GestureDetector( onTap: () { widget.onCurrencySelected?.call(currencyCode); }, child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(12), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), gradient: LinearGradient( colors: gradientColors, begin: Alignment.topLeft, end: Alignment.bottomRight, ), boxShadow: [ BoxShadow( color: gradientColors[0].withValues(alpha: isSelected ? 0.5 : 0.25), blurRadius: isSelected ? 12 : 6, offset: Offset(0, isSelected ? 4 : 2), ), ], border: isSelected ? Border.all( color: Colors.white.withValues(alpha: 0.8), width: 2, ) : Border.all( color: Colors.white.withValues(alpha: 0.15), width: 1, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ // Top row: flag + currency code Row( children: [ Container( width: 22, height: 22, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.white.withValues(alpha: 0.3), width: 1.5, ), ), child: ClipOval( child: Image.asset( 'assets/$flagAsset', fit: BoxFit.cover, errorBuilder: (_, __, ___) => Icon( Icons.monetization_on_outlined, size: 12, color: Colors.white.withValues(alpha: 0.8), ), ), ), ), const SizedBox(width: 6), Expanded( child: Text( currencyCode, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w700, color: Colors.white, letterSpacing: 0.5, ), ), ), if (isSelected) Container( width: 18, height: 18, decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.3), shape: BoxShape.circle, ), child: const Icon( Icons.check_rounded, size: 12, color: Colors.white, ), ), ], ), const SizedBox(height: 10), // Balance amount if (isLoading) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 70, height: 12, decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(4), ), ), ], ) else if (error != null) Row( children: [ Icon( Icons.error_outline_rounded, color: Colors.white.withValues(alpha: 0.7), size: 16, ), const SizedBox(width: 4), Text( 'Unavailable', style: TextStyle( fontSize: 10, fontWeight: FontWeight.w500, color: Colors.white.withValues(alpha: 0.7), ), ), ], ) else ...[ Text( _formatBalance(balance ?? 0.0), style: const TextStyle( fontSize: 17, fontWeight: FontWeight.w800, color: Colors.white, letterSpacing: 0.5, height: 1.1, ), ), ], ], ), ), ); } String _formatBalance(double balance) { final formatter = NumberFormat('#,##0.00', 'en_US'); return '\$${formatter.format(balance)}'; } }