// lib/widgets/balance_widget.dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../main.dart'; import '../services/wortis_api_service.dart'; class BalanceWidget extends StatefulWidget { final bool showIcon; final bool compact; final Color? textColor; final Color? backgroundColor; const BalanceWidget({ super.key, this.showIcon = true, this.compact = false, this.textColor, this.backgroundColor, }); @override _BalanceWidgetState createState() => _BalanceWidgetState(); } class _BalanceWidgetState extends State { bool _isRefreshing = false; DateTime _lastRefresh = DateTime.now(); @override void initState() { super.initState(); // Rafraîchir le solde au démarrage WidgetsBinding.instance.addPostFrameCallback((_) { _refreshBalance(); }); } Future _refreshBalance() async { final authController = Provider.of(context, listen: false); final agentId = authController.agentId; if (agentId == null || _isRefreshing) return; setState(() { _isRefreshing = true; }); try { // Test de connexion API d'abord final isConnected = await AuthApiService.testConnection(); if (isConnected) { final response = await AuthApiService.getAgentBalance(agentId); if (response['success'] == true && mounted) { final nouveauSolde = (response['solde'] ?? 0.0).toDouble(); authController.updateBalance(nouveauSolde); setState(() { _lastRefresh = DateTime.now(); }); // Afficher un message si le solde a changé significativement final ancienSolde = authController.balance; if ((nouveauSolde - ancienSolde).abs() > 100) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ Icon(Icons.refresh, color: Colors.white, size: 16), SizedBox(width: 8), Text( 'Solde mis à jour: ${nouveauSolde.toStringAsFixed(0)} XAF', ), ], ), backgroundColor: Colors.green, duration: Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ); } } } } catch (e) { print('Erreur rafraîchissement solde: $e'); } finally { if (mounted) { setState(() { _isRefreshing = false; }); } } } String _getTimeAgo() { final now = DateTime.now(); final difference = now.difference(_lastRefresh); if (difference.inMinutes < 1) { return 'À l\'instant'; } else if (difference.inMinutes < 60) { return 'Il y a ${difference.inMinutes}min'; } else { return 'Il y a ${difference.inHours}h'; } } @override Widget build(BuildContext context) { return Consumer( builder: (context, authController, child) { // Utiliser le solde actif (entreprise ou personnel selon le type de compte) final solde = authController.activeBalance; final isEnterprise = authController.isEnterpriseMember; final textColor = widget.textColor ?? Colors.white; if (widget.compact) { return GestureDetector( onTap: _refreshBalance, child: Container( padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: widget.backgroundColor ?? Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), border: Border.all( color: (widget.backgroundColor ?? Colors.white).withOpacity( 0.3, ), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ if (widget.showIcon) ...[ Icon( isEnterprise ? Icons.business_center : Icons.account_balance_wallet, color: textColor, size: 14, ), SizedBox(width: 6), ], if (_isRefreshing) SizedBox( width: 12, height: 12, child: CircularProgressIndicator( strokeWidth: 1.5, valueColor: AlwaysStoppedAnimation(textColor), ), ) else Text( '${solde.toStringAsFixed(0)} XAF', style: TextStyle( color: textColor, fontSize: 12, fontWeight: FontWeight.w600, ), ), ], ), ), ); } // Version étendue final enterpriseColor = Color(0xFF8B5CF6); final displayColor = isEnterprise ? enterpriseColor : Color(0xFF006699); return Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: widget.backgroundColor ?? Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( isEnterprise ? Icons.business_center : Icons.account_balance_wallet, color: displayColor, size: 24, ), SizedBox(width: 8), Flexible( child: Text( isEnterprise ? 'Solde entreprise' : 'Solde disponible', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black87, ), overflow: TextOverflow.ellipsis, ), ), ], ), if (isEnterprise && authController.enterprise?.nomEntreprise != null) ...[ SizedBox(height: 4), Text( authController.enterprise!.nomEntreprise, style: TextStyle( fontSize: 12, color: Colors.grey[600], ), overflow: TextOverflow.ellipsis, ), ], ], ), ), GestureDetector( onTap: _isRefreshing ? null : _refreshBalance, child: Container( padding: EdgeInsets.all(8), decoration: BoxDecoration( color: displayColor.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: _isRefreshing ? SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(displayColor), ), ) : Icon( Icons.refresh, color: displayColor, size: 16, ), ), ), ], ), SizedBox(height: 12), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Flexible( child: Text( solde.toStringAsFixed(0), style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: displayColor, ), overflow: TextOverflow.ellipsis, ), ), SizedBox(width: 8), Padding( padding: EdgeInsets.only(bottom: 4), child: Text( 'XAF', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey[600], ), ), ), ], ), SizedBox(height: 8), Row( children: [ Expanded( child: Text( 'Dernière mise à jour: ${_getTimeAgo()}', style: TextStyle(fontSize: 12, color: Colors.grey[500]), ), ), if (isEnterprise) Container( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: enterpriseColor.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.business, size: 10, color: enterpriseColor), SizedBox(width: 4), Text( 'PRO', style: TextStyle( fontSize: 10, color: enterpriseColor, fontWeight: FontWeight.bold, ), ), ], ), ), ], ), ], ), ); }, ); } }