import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:geosector_app/app.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:geosector_app/core/data/models/passage_model.dart'; import 'package:geosector_app/core/services/current_user_service.dart'; import 'package:geosector_app/core/theme/app_theme.dart'; import 'package:geosector_app/presentation/widgets/passage_form_dialog.dart'; /// Widget affichant 8 colonnes de statistiques de passages class BtnPassages extends StatelessWidget { final VoidCallback? onAddPassage; /// Callback appelé lors du clic sur un type de passage /// Si null, navigue vers /user/history (comportement par défaut) /// Si fourni, appelle ce callback avec le typeId (ou null pour "Tous") final Function(int? typeId)? onTypeSelected; /// Type de passage actuellement sélectionné (pour l'indicateur visuel) /// null = tous les passages final int? selectedTypeId; const BtnPassages({ super.key, this.onAddPassage, this.onTypeSelected, this.selectedTypeId, }); @override Widget build(BuildContext context) { // Récupérer l'utilisateur courant final currentUser = userRepository.getCurrentUser(); final currentOpeUserId = currentUser?.opeUserId; final currentOperation = userRepository.getCurrentOperation(); final isAdmin = CurrentUserService.instance.shouldShowAdminUI; // Vérifier si le type Lot doit être affiché final shouldShowLotType = _shouldShowLotType(); return SizedBox( height: 80, width: double.infinity, child: ValueListenableBuilder>( valueListenable: Hive.box(AppKeys.passagesBoxName).listenable(), builder: (context, box, child) { // Filtrer les passages de l'opération courante final allPassages = box.values.where((p) { if (currentOperation == null) return false; if (p.fkOperation != currentOperation.id) return false; // Mode Admin : afficher tous les passages de l'opération if (isAdmin) return true; // Mode Membre : logique spéciale pour type 2 (À finaliser) : afficher tous if (p.fkType == 2) return true; // Mode Membre : autres types : seulement les passages de l'utilisateur return p.fkUser == currentOpeUserId; }).toList(); // Calculer les statistiques par type final Map countsByType = {}; int totalPassages = 0; for (final passage in allPassages) { countsByType[passage.fkType] = (countsByType[passage.fkType] ?? 0) + 1; totalPassages++; } return Row( children: [ // Colonne 1 : Total (non cliquable) Expanded( child: _buildTotalColumn(context, totalPassages), ), const SizedBox(width: 2), // Colonnes 2-7 : Types de passages (cliquables) ...AppKeys.typesPassages.entries.expand((entry) { final typeId = entry.key; final typeInfo = entry.value; // Exclure le type Lot (5) si chkLotActif = false if (typeId == 5 && !shouldShowLotType) { return []; } final count = countsByType[typeId] ?? 0; final titre = typeInfo['titre'] as String; final couleur = Color(typeInfo['couleur2'] as int); final iconData = typeInfo['icon_data'] as IconData; return [ Expanded( child: _buildTypeColumn( context, typeId, titre, count, couleur, iconData, ), ), const SizedBox(width: 2), ]; }), // Colonne 8 : Bouton + (nouveau passage) Expanded( child: _buildAddColumn(context), ), ], ); }, ), ); } /// Colonne TOTAL (cliquable, affiche tous les passages) Widget _buildTotalColumn(BuildContext context, int total) { final bool isSelected = selectedTypeId == null; return InkWell( onTap: () async { if (onTypeSelected != null) { // Mode callback : appeler le callback avec null (tous les passages) onTypeSelected!(null); } else { // Mode navigation : sauvegarder dans Hive et naviguer try { if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) { await Hive.openBox(AppKeys.settingsBoxName); } final settingsBox = Hive.box(AppKeys.settingsBoxName); await settingsBox.delete('history_selectedTypeId'); debugPrint('BtnPassages: Filtre type réinitialisé (tous les passages)'); } catch (e) { debugPrint('Erreur réinitialisation filtre: $e'); } // Navigation vers /history avec GoRouter (détection automatique admin/user) if (context.mounted) { final isAdmin = CurrentUserService.instance.shouldShowAdminUI; context.go(isAdmin ? '/admin/history' : '/user/history'); } } }, child: Container( height: 80, decoration: BoxDecoration( color: Colors.grey[200], border: Border.all( color: Colors.grey[400]!, width: isSelected ? 5 : 1, ), borderRadius: const BorderRadius.only( topLeft: Radius.circular(AppTheme.borderRadiusMedium), bottomLeft: Radius.circular(AppTheme.borderRadiusMedium), ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ const Icon( Icons.route, size: 20, color: Colors.black54, ), const SizedBox(height: 2), Text( total.toString(), style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 2), Text( total > 1 ? 'passages' : 'passage', style: TextStyle( fontSize: 10, color: Colors.grey[700], ), textAlign: TextAlign.center, ), ], ), ), ); } /// Colonne TYPE DE PASSAGE (cliquable, navigue vers /history avec filtre) Widget _buildTypeColumn( BuildContext context, int typeId, String titre, int count, Color couleur, IconData iconData, ) { final bool isSelected = selectedTypeId == typeId; return InkWell( onTap: () async { if (onTypeSelected != null) { // Mode callback : appeler le callback avec le typeId onTypeSelected!(typeId); } else { // Mode navigation : sauvegarder dans Hive et naviguer try { if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) { await Hive.openBox(AppKeys.settingsBoxName); } final settingsBox = Hive.box(AppKeys.settingsBoxName); await settingsBox.put('history_selectedTypeId', typeId); debugPrint('BtnPassages: Type $typeId sauvegardé dans Hive'); } catch (e) { debugPrint('Erreur sauvegarde type: $e'); } // Navigation vers /history avec GoRouter (détection automatique admin/user) if (context.mounted) { final isAdmin = CurrentUserService.instance.shouldShowAdminUI; context.go(isAdmin ? '/admin/history' : '/user/history'); } } }, child: Container( height: 80, decoration: BoxDecoration( color: couleur.withOpacity(0.1), border: Border.all( color: couleur, width: isSelected ? 5 : 1, ), borderRadius: BorderRadius.circular(4), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( iconData, size: 20, color: couleur, ), const SizedBox(height: 2), Text( count.toString(), style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: couleur, ), ), const SizedBox(height: 2), Padding( padding: const EdgeInsets.symmetric(horizontal: 2), child: Text( titre, style: TextStyle( fontSize: 10, color: couleur, ), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ), ); } /// Colonne NOUVEAU PASSAGE (bouton +, fond vert) Widget _buildAddColumn(BuildContext context) { return InkWell( onTap: () { if (onAddPassage != null) { onAddPassage!(); } else { // Par défaut, ouvrir le dialogue de création _showPassageFormDialog(context); } }, child: Container( height: 80, decoration: BoxDecoration( color: AppTheme.buttonSuccessColor.withOpacity(0.1), border: Border.all( color: AppTheme.buttonSuccessColor, width: 1, ), borderRadius: const BorderRadius.only( topRight: Radius.circular(AppTheme.borderRadiusMedium), bottomRight: Radius.circular(AppTheme.borderRadiusMedium), ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon( Icons.add_circle_outline, size: 24, color: AppTheme.buttonSuccessColor, ), const SizedBox(height: 2), Text( 'Nouveau', style: TextStyle( fontSize: 10, color: AppTheme.buttonSuccessColor, fontWeight: FontWeight.w600, ), textAlign: TextAlign.center, ), ], ), ), ); } /// Vérifier si le type Lot doit être affiché bool _shouldShowLotType() { final currentUser = userRepository.getCurrentUser(); if (currentUser != null && currentUser.fkEntite != null) { final userAmicale = amicaleRepository.getAmicaleById(currentUser.fkEntite!); if (userAmicale != null) { return userAmicale.chkLotActif; } } return true; // Par défaut, on affiche } /// Afficher le dialogue de création de passage Future _showPassageFormDialog(BuildContext context) async { await showDialog( context: context, builder: (context) => PassageFormDialog( title: 'Nouveau passage', readOnly: false, passageRepository: passageRepository, userRepository: userRepository, operationRepository: operationRepository, amicaleRepository: amicaleRepository, onSuccess: () { debugPrint('BtnPassages: Passage créé avec succès'); }, ), ); } }