import 'package:flutter/material.dart'; import 'package:geosector_app/core/data/models/passage_model.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:geosector_app/core/utils/api_exception.dart'; import 'package:geosector_app/core/services/current_amicale_service.dart'; import 'package:geosector_app/presentation/widgets/passage_form_dialog.dart'; import 'package:geosector_app/app.dart'; class PassageMapDialog extends StatelessWidget { final PassageModel passage; final bool isAdmin; final VoidCallback? onDeleted; const PassageMapDialog({ super.key, required this.passage, this.isAdmin = false, this.onDeleted, }); @override Widget build(BuildContext context) { final int type = passage.fkType; // Récupérer le type de passage final String typePassage = AppKeys.typesPassages[type]?['titre'] ?? 'Inconnu'; // Utiliser couleur2 pour le badge (couleur1 peut être blanche pour type 2) final Color typeColor = Color(AppKeys.typesPassages[type]?['couleur2'] ?? 0xFF9E9E9E); // Construire l'adresse complète final String adresse = '${passage.numero} ${passage.rueBis} ${passage.rue}'.trim(); // Vérifier si l'utilisateur peut supprimer (admin ou user avec permission) bool canDelete = isAdmin; if (!isAdmin) { try { final amicale = CurrentAmicaleService.instance.currentAmicale; if (amicale != null) { canDelete = amicale.chkUserDeletePass == true; } } catch (e) { debugPrint('Erreur lors de la vérification des permissions: $e'); } } return AlertDialog( title: Row( children: [ Container( width: 10, height: 10, decoration: BoxDecoration( color: typeColor, shape: BoxShape.circle, ), ), const SizedBox(width: 8), Expanded( child: Text( typePassage, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), ], ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Adresse _buildInfoRow(Icons.location_on, 'Adresse', adresse.isEmpty ? 'Non renseignée' : adresse), // Ville if (passage.ville.isNotEmpty) _buildInfoRow(Icons.location_city, 'Ville', passage.ville), // Type d'habitat if (passage.fkHabitat == 1) _buildInfoRow(Icons.home, 'Habitat', 'Maison') else if (passage.fkHabitat == 2) ...[ _buildInfoRow( Icons.home, 'Habitat', 'Appartement${passage.niveau.isNotEmpty || passage.appt.isNotEmpty ? ' (' : ''}${passage.niveau.isNotEmpty ? 'Niveau ${passage.niveau}' : ''}${passage.niveau.isNotEmpty && passage.appt.isNotEmpty ? ', ' : ''}${passage.appt.isNotEmpty ? 'Appt ${passage.appt}' : ''}${passage.niveau.isNotEmpty || passage.appt.isNotEmpty ? ')' : ''}', ), ], // Résidence if (passage.residence.isNotEmpty) _buildInfoRow(Icons.apartment, 'Résidence', passage.residence), // Nom if (passage.name.isNotEmpty) _buildInfoRow(Icons.person, 'Nom', passage.name), // Remarque if (passage.remarque.isNotEmpty) _buildInfoRow(Icons.note, 'Remarque', passage.remarque), ], ), actions: [ // Bouton de modification TextButton.icon( onPressed: () { Navigator.of(context).pop(); _showEditDialog(context); }, icon: const Icon(Icons.edit, size: 20), label: const Text('Modifier'), style: TextButton.styleFrom( foregroundColor: Colors.blue, ), ), // Bouton de suppression si autorisé if (canDelete) TextButton.icon( onPressed: () { Navigator.of(context).pop(); _showDeleteConfirmationDialog(context); }, icon: const Icon(Icons.delete, size: 20), label: const Text('Supprimer'), style: TextButton.styleFrom( foregroundColor: Colors.red, ), ), // Bouton de fermeture TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Fermer'), ), ], ); } // Helper pour construire une ligne d'information Widget _buildInfoRow(IconData icon, String label, String value) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(icon, size: 16, color: Colors.grey[600]), const SizedBox(width: 8), Expanded( child: RichText( text: TextSpan( style: const TextStyle(color: Colors.black87), children: [ TextSpan( text: '$label: ', style: const TextStyle(fontWeight: FontWeight.w600), ), TextSpan(text: value), ], ), ), ), ], ), ); } // Afficher le dialog de modification void _showEditDialog(BuildContext context) { showDialog( context: context, builder: (BuildContext dialogContext) { return PassageFormDialog( passage: passage, title: 'Modifier le passage', passageRepository: passageRepository, userRepository: userRepository, operationRepository: operationRepository, amicaleRepository: amicaleRepository, onSuccess: () { // Appeler le callback si fourni pour rafraîchir l'affichage onDeleted?.call(); }, ); }, ); } // Afficher le dialog de confirmation de suppression void _showDeleteConfirmationDialog(BuildContext context) { final TextEditingController confirmController = TextEditingController(); final String streetNumber = passage.numero; final String fullAddress = '${passage.numero} ${passage.rueBis} ${passage.rue}'.trim(); showDialog( context: context, barrierDismissible: false, builder: (BuildContext dialogContext) { return AlertDialog( title: const Row( children: [ Icon(Icons.warning, color: Colors.red, size: 28), SizedBox(width: 8), Text('Confirmation de suppression'), ], ), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'ATTENTION : Cette action est irréversible !', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.red, fontSize: 16, ), ), const SizedBox(height: 16), Text( 'Vous êtes sur le point de supprimer définitivement le passage :', style: TextStyle(color: Colors.grey[800]), ), const SizedBox(height: 8), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.grey[300]!), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( fullAddress.isEmpty ? 'Adresse inconnue' : fullAddress, style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 14, ), ), if (passage.ville.isNotEmpty) ...[ const SizedBox(height: 4), Text( passage.ville, style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ], ), ), const SizedBox(height: 20), const Text( 'Pour confirmer la suppression, veuillez saisir le numéro de rue de ce passage :', style: TextStyle(fontWeight: FontWeight.w500), ), const SizedBox(height: 12), TextField( controller: confirmController, decoration: InputDecoration( labelText: 'Numéro de rue', hintText: streetNumber.isNotEmpty ? 'Ex: $streetNumber' : 'Saisir le numéro', border: const OutlineInputBorder(), prefixIcon: const Icon(Icons.home), ), keyboardType: TextInputType.text, textCapitalization: TextCapitalization.characters, ), ], ), ), actions: [ TextButton( onPressed: () { confirmController.dispose(); Navigator.of(dialogContext).pop(); }, child: const Text('Annuler'), ), ElevatedButton( onPressed: () async { // Vérifier que le numéro saisi correspond final enteredNumber = confirmController.text.trim(); if (enteredNumber.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Veuillez saisir le numéro de rue'), backgroundColor: Colors.orange, ), ); return; } if (streetNumber.isNotEmpty && enteredNumber.toUpperCase() != streetNumber.toUpperCase()) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Le numéro de rue ne correspond pas'), backgroundColor: Colors.red, ), ); return; } // Fermer le dialog confirmController.dispose(); Navigator.of(dialogContext).pop(); // Effectuer la suppression await _deletePassage(context); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), child: const Text('Supprimer définitivement'), ), ], ); }, ); } // Supprimer un passage Future _deletePassage(BuildContext context) async { try { // Appeler le repository pour supprimer via l'API final success = await passageRepository.deletePassageViaApi(passage.id); if (success && context.mounted) { ApiException.showSuccess(context, 'Passage supprimé avec succès'); // Appeler le callback si fourni onDeleted?.call(); } else if (context.mounted) { ApiException.showError( context, Exception('Erreur lors de la suppression')); } } catch (e) { debugPrint('Erreur suppression passage: $e'); if (context.mounted) { ApiException.showError(context, e); } } } }