import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; import '../../../../core/models/membre_search_result.dart'; /// Widget d'affichage des statistiques de recherche /// Présente les métriques et graphiques des résultats de recherche class SearchStatisticsCard extends StatelessWidget { final SearchStatistics statistics; const SearchStatisticsCard({ super.key, required this.statistics, }); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Titre Row( children: [ Icon( Icons.analytics, color: Theme.of(context).primaryColor, size: 24, ), const SizedBox(width: 8), Text( 'Statistiques de Recherche', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 24), // Métriques principales _buildMainMetrics(context), const SizedBox(height: 24), // Graphique de répartition actifs/inactifs _buildStatusChart(context), const SizedBox(height: 24), // Métriques détaillées _buildDetailedMetrics(context), const SizedBox(height: 24), // Informations complémentaires _buildAdditionalInfo(context), ], ), ); } /// Métriques principales Widget _buildMainMetrics(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Vue d\'ensemble', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildMetricCard( context, 'Total Membres', statistics.totalMembres.toString(), Icons.people, Colors.blue, ), ), const SizedBox(width: 12), Expanded( child: _buildMetricCard( context, 'Membres Actifs', statistics.membresActifs.toString(), Icons.person, Colors.green, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildMetricCard( context, 'Âge Moyen', '${statistics.ageMoyen.toStringAsFixed(1)} ans', Icons.cake, Colors.orange, ), ), const SizedBox(width: 12), Expanded( child: _buildMetricCard( context, 'Ancienneté', '${statistics.ancienneteMoyenne.toStringAsFixed(1)} ans', Icons.schedule, Colors.purple, ), ), ], ), ], ), ), ); } /// Carte de métrique individuelle Widget _buildMetricCard( BuildContext context, String title, String value, IconData icon, Color color, ) { return Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all(color: color.withOpacity(0.3)), ), child: Column( children: [ Icon(icon, color: color, size: 24), const SizedBox(height: 8), Text( value, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, color: color, ), ), Text( title, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Colors.grey[600], ), textAlign: TextAlign.center, ), ], ), ); } /// Graphique de répartition des statuts Widget _buildStatusChart(BuildContext context) { if (statistics.totalMembres == 0) { return const SizedBox.shrink(); } return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Répartition par Statut', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), SizedBox( height: 200, child: Row( children: [ // Graphique en secteurs Expanded( flex: 2, child: PieChart( PieChartData( sections: [ PieChartSectionData( value: statistics.membresActifs.toDouble(), title: '${statistics.pourcentageActifs.toStringAsFixed(1)}%', color: Colors.green, radius: 60, titleStyle: const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white, ), ), if (statistics.membresInactifs > 0) PieChartSectionData( value: statistics.membresInactifs.toDouble(), title: '${statistics.pourcentageInactifs.toStringAsFixed(1)}%', color: Colors.orange, radius: 60, titleStyle: const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], sectionsSpace: 2, centerSpaceRadius: 40, ), ), ), // Légende Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildLegendItem( 'Actifs', statistics.membresActifs, Colors.green, ), const SizedBox(height: 8), if (statistics.membresInactifs > 0) _buildLegendItem( 'Inactifs', statistics.membresInactifs, Colors.orange, ), ], ), ), ], ), ), ], ), ), ); } /// Item de légende Widget _buildLegendItem(String label, int count, Color color) { return Row( children: [ Container( width: 12, height: 12, decoration: BoxDecoration( color: color, shape: BoxShape.circle, ), ), const SizedBox(width: 8), Expanded( child: Text( '$label ($count)', style: const TextStyle(fontSize: 12), ), ), ], ); } /// Métriques détaillées Widget _buildDetailedMetrics(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Détails Démographiques', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), _buildDetailRow( context, 'Tranche d\'âge', statistics.trancheAge, Icons.calendar_today, ), _buildDetailRow( context, 'Organisations', '${statistics.nombreOrganisations} représentées', Icons.business, ), _buildDetailRow( context, 'Régions', '${statistics.nombreRegions} représentées', Icons.location_on, ), _buildDetailRow( context, 'Taux d\'activité', '${statistics.pourcentageActifs.toStringAsFixed(1)}%', Icons.trending_up, ), ], ), ), ); } /// Ligne de détail Widget _buildDetailRow( BuildContext context, String label, String value, IconData icon, ) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( children: [ Icon( icon, size: 20, color: Colors.grey[600], ), const SizedBox(width: 12), Expanded( child: Text( label, style: Theme.of(context).textTheme.bodyMedium, ), ), Text( value, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), ); } /// Informations complémentaires Widget _buildAdditionalInfo(BuildContext context) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.info_outline, color: Theme.of(context).primaryColor, ), const SizedBox(width: 8), Text( 'Informations Complémentaires', style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 16), Text( statistics.description, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Colors.grey[700], ), ), const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12.0), decoration: BoxDecoration( color: Colors.blue.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.blue.withOpacity(0.3)), ), child: Row( children: [ const Icon(Icons.lightbulb, color: Colors.blue), const SizedBox(width: 8), Expanded( child: Text( 'Ces statistiques sont calculées en temps réel sur les résultats de votre recherche.', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Colors.blue[700], ), ), ), ], ), ), ], ), ), ); } }