import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:geosector_app/core/data/models/passage_model.dart'; import 'package:geosector_app/core/data/models/sector_model.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:geosector_app/shared/app_theme.dart'; class SectorDistributionCard extends StatefulWidget { final String title; final double? height; final EdgeInsetsGeometry? padding; const SectorDistributionCard({ Key? key, this.title = 'Répartition par secteur', this.height, this.padding, }) : super(key: key); @override State createState() => _SectorDistributionCardState(); } class _SectorDistributionCardState extends State { List> sectorStats = []; bool isLoading = true; @override void initState() { super.initState(); _loadSectorData(); } Future _loadSectorData() async { setState(() { isLoading = true; }); try { // S'assurer que les boîtes Hive sont ouvertes if (!Hive.isBoxOpen(AppKeys.sectorsBoxName)) { await Hive.openBox(AppKeys.sectorsBoxName); } if (!Hive.isBoxOpen(AppKeys.passagesBoxName)) { await Hive.openBox(AppKeys.passagesBoxName); } // Récupérer tous les secteurs final sectorsBox = Hive.box(AppKeys.sectorsBoxName); final List sectors = sectorsBox.values.toList(); // Récupérer tous les passages final passagesBox = Hive.box(AppKeys.passagesBoxName); final List passages = passagesBox.values.toList(); // Compter les passages par secteur (en excluant ceux où fkType==2) final Map sectorCounts = {}; for (final passage in passages) { // Exclure les passages où fkType==2 if (passage.fkSector != null && passage.fkType != 2) { sectorCounts[passage.fkSector!] = (sectorCounts[passage.fkSector!] ?? 0) + 1; } } // Préparer les données pour l'affichage List> stats = []; for (final sector in sectors) { final count = sectorCounts[sector.id] ?? 0; if (count > 0) { stats.add({ 'name': sector.libelle, 'count': count, 'color': sector.color.isEmpty ? 0xFF4B77BE : int.tryParse(sector.color.replaceAll('#', '0xFF')) ?? 0xFF4B77BE, }); } } setState(() { sectorStats = stats; isLoading = false; }); } catch (e) { debugPrint('Erreur lors du chargement des données de secteur: $e'); setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { return Container( height: widget.height, padding: widget.padding ?? const EdgeInsets.all(AppTheme.spacingM), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(AppTheme.borderRadiusMedium), boxShadow: AppTheme.cardShadow, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.title, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16, ), ), if (isLoading) const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) else IconButton( icon: const Icon(Icons.refresh, size: 20), onPressed: _loadSectorData, tooltip: 'Rafraîchir', padding: EdgeInsets.zero, constraints: const BoxConstraints(), ), ], ), const SizedBox(height: AppTheme.spacingM), Expanded( child: isLoading ? const Center(child: CircularProgressIndicator()) : sectorStats.isEmpty ? const Center( child: Text('Aucune donnée de secteur disponible')) : ListView.builder( itemCount: sectorStats.length, itemBuilder: (context, index) { final sector = sectorStats[index]; return _buildSectorItem( context, sector['name'], sector['count'], Color(sector['color']), ); }, ), ), ], ), ); } Widget _buildSectorItem( BuildContext context, String name, int count, Color color, ) { final totalCount = sectorStats.fold(0, (sum, item) => sum + (item['count'] as int)); final percentage = totalCount > 0 ? (count / totalCount) * 100 : 0; return Padding( padding: const EdgeInsets.only(bottom: AppTheme.spacingS), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( name, style: const TextStyle(fontSize: 14), overflow: TextOverflow.ellipsis, ), ), Text( '$count (${percentage.toInt()}%)', style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, ), ), ], ), const SizedBox(height: 4), LinearProgressIndicator( value: percentage / 100, backgroundColor: Colors.grey[200], valueColor: AlwaysStoppedAnimation(color), minHeight: 8, borderRadius: BorderRadius.circular(4), ), ], ), ); } }