import 'dart:async'; import 'package:flutter/material.dart'; import '../../data/models/souscription_status_model.dart'; import '../../../../features/authentication/presentation/bloc/auth_bloc.dart'; import '../../../../shared/design_system/tokens/unionflow_colors.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// Page de secours — affichée si l'auto-activation échoue après paiement. /// Normalement jamais vue : confirmerPaiement() active le compte côté backend. class AwaitingValidationPage extends StatefulWidget { final SouscriptionStatusModel? souscription; const AwaitingValidationPage({super.key, this.souscription}); @override State createState() => _AwaitingValidationPageState(); } class _AwaitingValidationPageState extends State with SingleTickerProviderStateMixin { late AnimationController _pulseController; late Animation _pulseAnimation; Timer? _refreshTimer; int _checkCount = 0; @override void initState() { super.initState(); _pulseController = AnimationController( vsync: this, duration: const Duration(seconds: 2), )..repeat(reverse: true); _pulseAnimation = Tween(begin: 0.88, end: 1.0).animate( CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut), ); // Vérification périodique toutes les 15 secondes _refreshTimer = Timer.periodic(const Duration(seconds: 15), (_) { if (mounted) { setState(() => _checkCount++); context.read().add(const AuthStatusChecked()); } }); } @override void dispose() { _pulseController.dispose(); _refreshTimer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final sosc = widget.souscription; return Scaffold( backgroundColor: UnionFlowColors.background, body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(28), child: Column( children: [ const SizedBox(height: 32), // Animation pulsante ScaleTransition( scale: _pulseAnimation, child: Container( width: 130, height: 130, decoration: BoxDecoration( shape: BoxShape.circle, color: UnionFlowColors.goldPale, border: Border.all( color: UnionFlowColors.gold.withOpacity(0.5), width: 3), boxShadow: UnionFlowColors.goldGlowShadow, ), child: const Icon( Icons.hourglass_top_rounded, size: 64, color: UnionFlowColors.gold, ), ), ), const SizedBox(height: 32), const Text( 'Paiement reçu !', style: TextStyle( fontSize: 26, fontWeight: FontWeight.w800, color: UnionFlowColors.textPrimary, ), textAlign: TextAlign.center, ), const SizedBox(height: 10), const Text( 'Votre paiement a bien été reçu. Votre compte\nest en cours d\'activation.', style: TextStyle( fontSize: 15, color: UnionFlowColors.textSecondary, height: 1.5, ), textAlign: TextAlign.center, ), const SizedBox(height: 32), // Souscription recap card if (sosc != null) _RecapCard(souscription: sosc), const SizedBox(height: 24), // État de vérification Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: UnionFlowColors.surface, borderRadius: BorderRadius.circular(14), boxShadow: UnionFlowColors.softShadow, ), child: Row( children: [ SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2.5, color: UnionFlowColors.unionGreen, value: _checkCount > 0 ? null : null, ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Vérification automatique en cours', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 13, color: UnionFlowColors.textPrimary, ), ), Text( 'Vérifié $_checkCount fois · prochaine dans 15s', style: const TextStyle( fontSize: 11, color: UnionFlowColors.textSecondary, ), ), ], ), ), ], ), ), const SizedBox(height: 20), // Note d'information Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: UnionFlowColors.infoPale, borderRadius: BorderRadius.circular(12), border: Border.all(color: UnionFlowColors.info.withOpacity(0.2)), ), child: const Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Icons.info_outline_rounded, color: UnionFlowColors.info, size: 18), SizedBox(width: 10), Expanded( child: Text( 'L\'activation est généralement immédiate. Si votre compte n\'est pas activé dans les 5 minutes, contactez notre support.', style: TextStyle( fontSize: 12, color: UnionFlowColors.info, height: 1.45), ), ), ], ), ), const SizedBox(height: 28), SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: () => context.read().add(const AuthStatusChecked()), icon: const Icon(Icons.refresh_rounded), label: const Text( 'Vérifier maintenant', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700), ), style: ElevatedButton.styleFrom( backgroundColor: UnionFlowColors.unionGreen, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14)), shadowColor: UnionFlowColors.unionGreen.withOpacity(0.3), elevation: 2, ), ), ), const SizedBox(height: 12), TextButton( onPressed: () => context.read().add(const AuthLogoutRequested()), child: const Text( 'Se déconnecter', style: TextStyle(color: UnionFlowColors.textSecondary), ), ), ], ), ), ), ); } } class _RecapCard extends StatelessWidget { final SouscriptionStatusModel souscription; const _RecapCard({required this.souscription}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: UnionFlowColors.surface, borderRadius: BorderRadius.circular(14), boxShadow: UnionFlowColors.softShadow, border: Border.all(color: UnionFlowColors.border), ), child: Column( children: [ _Row( icon: Icons.business_rounded, label: 'Organisation', value: souscription.organisationNom ?? '—', ), const Divider(height: 16, color: UnionFlowColors.border), _Row( icon: Icons.workspace_premium_rounded, label: 'Formule', value: souscription.typeFormule, ), const SizedBox(height: 8), _Row( icon: Icons.calendar_today_rounded, label: 'Période', value: souscription.typePeriode, ), if (souscription.montantTotal != null) ...[ const SizedBox(height: 8), _Row( icon: Icons.payments_rounded, label: 'Montant payé', value: '${souscription.montantTotal!.toStringAsFixed(0)} FCFA', valueColor: UnionFlowColors.unionGreen, valueBold: true, ), ], ], ), ); } } class _Row extends StatelessWidget { final IconData icon; final String label; final String value; final Color valueColor; final bool valueBold; const _Row({ required this.icon, required this.label, required this.value, this.valueColor = UnionFlowColors.textPrimary, this.valueBold = false, }); @override Widget build(BuildContext context) { return Row( children: [ Icon(icon, size: 16, color: UnionFlowColors.textTertiary), const SizedBox(width: 8), Text( label, style: const TextStyle( color: UnionFlowColors.textSecondary, fontSize: 13), ), const Spacer(), Text( value, style: TextStyle( color: valueColor, fontSize: 13, fontWeight: valueBold ? FontWeight.w700 : FontWeight.w500, ), ), ], ); } }