import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/services/location_service.dart';
import 'package:geosector_app/presentation/widgets/mapbox_map.dart';

import '../../core/constants/app_keys.dart';
import '../../core/data/models/sector_model.dart';
import '../../core/data/models/passage_model.dart';

// Extension pour ajouter ln2 (logarithme népérien de 2) comme constante
extension MathConstants on math.Random {
  static const double ln2 = 0.6931471805599453; // ln(2)
}

class UserMapPage extends StatefulWidget {
  const UserMapPage({super.key});

  @override
  State<UserMapPage> createState() => _UserMapPageState();
}

class _UserMapPageState extends State<UserMapPage> {
  // Contrôleur de carte
  final MapController _mapController = MapController();

  // Position actuelle et zoom
  LatLng _currentPosition =
      const LatLng(48.117266, -1.6777926); // Position initiale sur Rennes
  double _currentZoom = 12.0; // Zoom initial

  // Données des secteurs et passages
  final List<Map<String, dynamic>> _sectors = [];
  final List<Map<String, dynamic>> _passages = [];

  // État du plein écran
  bool _isFullScreen = false;

  // Items pour la combobox de secteurs
  List<DropdownMenuItem<int?>> _sectorItems = [];

  // Filtres pour les types de passages
  bool _showEffectues = true;
  bool _showAFinaliser = true;
  bool _showRefuses = true;
  bool _showDons = true;
  bool _showLots = true;
  bool _showMaisonsVides = true;

  // Référence à la boîte Hive pour les paramètres
  late Box _settingsBox;

  // Vérifier si la combobox de secteurs doit être affichée
  bool get _shouldShowSectorCombobox => _sectors.length > 1;

  int? _selectedSectorId;

  @override
  void initState() {
    super.initState();
    _initSettings().then((_) {
      _loadSectors();
      _loadPassages();
    });
  }

  // Initialiser la boîte de paramètres et charger les préférences
  Future<void> _initSettings() async {
    // Ouvrir la boîte de paramètres si elle n'est pas déjà ouverte
    if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) {
      _settingsBox = await Hive.openBox(AppKeys.settingsBoxName);
    } else {
      _settingsBox = Hive.box(AppKeys.settingsBoxName);
    }

    // Charger les filtres sauvegardés
    _showEffectues = _settingsBox.get('showEffectues', defaultValue: true);
    _showAFinaliser = _settingsBox.get('showAFinaliser', defaultValue: true);
    _showRefuses = _settingsBox.get('showRefuses', defaultValue: true);
    _showDons = _settingsBox.get('showDons', defaultValue: true);
    _showLots = _settingsBox.get('showLots', defaultValue: true);
    _showMaisonsVides =
        _settingsBox.get('showMaisonsVides', defaultValue: true);

    // Charger le secteur sélectionné
    _selectedSectorId = _settingsBox.get('selectedSectorId');

    // Charger la position et le zoom
    final double? savedLat = _settingsBox.get('mapLat');
    final double? savedLng = _settingsBox.get('mapLng');
    final double? savedZoom = _settingsBox.get('mapZoom');

    if (savedLat != null && savedLng != null) {
      _currentPosition = LatLng(savedLat, savedLng);
    }

    if (savedZoom != null) {
      _currentZoom = savedZoom;
    }
  }

  // Obtenir la position actuelle de l'utilisateur
  Future<void> _getUserLocation() async {
    try {
      // Afficher un indicateur de chargement
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('Recherche de votre position...'),
          duration: Duration(seconds: 2),
        ),
      );

      // Obtenir la position actuelle via le service de géolocalisation
      final position = await LocationService.getCurrentPosition();

      if (position != null) {
        // Mettre à jour la position sur la carte
        _updateMapPosition(position, zoom: 17);

        // Sauvegarder la nouvelle position
        _settingsBox.put('mapLat', position.latitude);
        _settingsBox.put('mapLng', position.longitude);

        // Informer l'utilisateur
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Position actualisée'),
              backgroundColor: Colors.green,
              duration: Duration(seconds: 1),
            ),
          );
        }
      } else {
        // Informer l'utilisateur en cas d'échec
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text(
                  'Impossible d\'obtenir votre position. Vérifiez vos paramètres de localisation.'),
              backgroundColor: Colors.red,
            ),
          );
        }
      }
    } catch (e) {
      // Gérer les erreurs
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Erreur: $e'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  // Sauvegarder les paramètres utilisateur
  void _saveSettings() {
    // Sauvegarder les filtres
    _settingsBox.put('showEffectues', _showEffectues);
    _settingsBox.put('showAFinaliser', _showAFinaliser);
    _settingsBox.put('showRefuses', _showRefuses);
    _settingsBox.put('showDons', _showDons);
    _settingsBox.put('showLots', _showLots);
    _settingsBox.put('showMaisonsVides', _showMaisonsVides);

    // Sauvegarder le secteur sélectionné
    if (_selectedSectorId != null) {
      _settingsBox.put('selectedSectorId', _selectedSectorId);
    }

    // Sauvegarder la position et le zoom actuels
    _settingsBox.put('mapLat', _currentPosition.latitude);
    _settingsBox.put('mapLng', _currentPosition.longitude);
    _settingsBox.put('mapZoom', _currentZoom);
  }

  // Charger les secteurs depuis la boîte Hive
  void _loadSectors() {
    try {
      final sectorsBox = Hive.box<SectorModel>(AppKeys.sectorsBoxName);
      final sectors = sectorsBox.values.toList();

      setState(() {
        _sectors.clear();

        for (final sector in sectors) {
          final List<List<double>> coordinates = sector.getCoordinates();
          final List<LatLng> points =
              coordinates.map((coord) => LatLng(coord[0], coord[1])).toList();

          if (points.isNotEmpty) {
            _sectors.add({
              'id': sector.id,
              'name': sector.libelle,
              'color': _hexToColor(sector.color),
              'points': points,
            });
          }
        }

        // Mettre à jour les items de la combobox de secteurs
        _updateSectorItems();

        // Si un secteur était sélectionné précédemment, le centrer
        if (_selectedSectorId != null &&
            _sectors.any((s) => s['id'] == _selectedSectorId)) {
          _centerMapOnSpecificSector(_selectedSectorId!);
        }
        // Sinon, centrer la carte sur tous les secteurs
        else if (_sectors.isNotEmpty) {
          _centerMapOnSectors();
        }
      });
    } catch (e) {
      debugPrint('Erreur lors du chargement des secteurs: $e');
    }
  }

  // Mettre à jour les items de la combobox de secteurs
  void _updateSectorItems() {
    // Créer l'item "Tous les secteurs"
    final List<DropdownMenuItem<int?>> items = [
      const DropdownMenuItem<int?>(
        value: null,
        child: Text('Tous les secteurs'),
      ),
    ];

    // Ajouter tous les secteurs
    for (final sector in _sectors) {
      items.add(
        DropdownMenuItem<int?>(
          value: sector['id'] as int,
          child: Text(sector['name'] as String),
        ),
      );
    }

    setState(() {
      _sectorItems = items;
    });
  }

  // Charger les passages depuis la boîte Hive
  void _loadPassages() {
    try {
      // Récupérer la boîte des passages
      final passagesBox = Hive.box<PassageModel>(AppKeys.passagesBoxName);

      // Créer une nouvelle liste temporaire
      final List<Map<String, dynamic>> newPassages = [];

      // Parcourir tous les passages dans la boîte
      for (var i = 0; i < passagesBox.length; i++) {
        final passage = passagesBox.getAt(i);
        if (passage != null) {
          // Vérifier si les coordonnées GPS sont valides
          final lat = double.tryParse(passage.gpsLat);
          final lng = double.tryParse(passage.gpsLng);

          // Filtrer par secteur si un secteur est sélectionné
          if (_selectedSectorId != null &&
              passage.fkSector != _selectedSectorId) {
            continue;
          }

          if (lat != null && lng != null) {
            // Obtenir la couleur du type de passage
            Color passageColor = Colors.grey; // Couleur par défaut

            // Vérifier si le type de passage existe dans AppKeys.typesPassages
            if (AppKeys.typesPassages.containsKey(passage.fkType)) {
              // Utiliser la couleur1 du type de passage
              final colorValue =
                  AppKeys.typesPassages[passage.fkType]!['couleur1'] as int;
              passageColor = Color(colorValue);

              // Ajouter le passage à la liste temporaire avec filtrage
              if (_shouldShowPassage(passage.fkType)) {
                newPassages.add({
                  'id': passage.id,
                  'position': LatLng(lat, lng),
                  'type': passage.fkType,
                  'color': passageColor,
                  'model': passage, // Ajouter le modèle complet
                });
              }
            }
          }
        }
      }

      // Mettre à jour la liste des passages dans l'état
      setState(() {
        _passages.clear();
        _passages.addAll(newPassages);
      });

      // Sauvegarder les paramètres après chargement des passages
      _saveSettings();
    } catch (e) {
      debugPrint('Erreur lors du chargement des passages: $e');
    }
  }

  // Vérifier si un passage doit être affiché en fonction de son type
  bool _shouldShowPassage(int type) {
    switch (type) {
      case 1: // Effectué
        return _showEffectues;
      case 2: // À finaliser
        return _showAFinaliser;
      case 3: // Refusé
        return _showRefuses;
      case 4: // Don
        return _showDons;
      case 5: // Lot
        return _showLots;
      case 6: // Maison vide
        return _showMaisonsVides;
      default:
        return true;
    }
  }

  // Convertir une couleur hexadécimale en Color
  Color _hexToColor(String hexColor) {
    // Supprimer le # si présent
    final String colorStr =
        hexColor.startsWith('#') ? hexColor.substring(1) : hexColor;

    // Ajouter FF pour l'opacité si nécessaire (6 caractères -> 8 caractères)
    final String fullColorStr = colorStr.length == 6 ? 'FF$colorStr' : colorStr;

    // Convertir en entier et créer la couleur
    return Color(int.parse(fullColorStr, radix: 16));
  }

  // Centrer la carte sur tous les secteurs
  void _centerMapOnSectors() {
    if (_sectors.isEmpty) return;

    // Trouver les limites de tous les secteurs
    double minLat = 90.0;
    double maxLat = -90.0;
    double minLng = 180.0;
    double maxLng = -180.0;

    for (final sector in _sectors) {
      final points = sector['points'] as List<LatLng>;
      for (final point in points) {
        minLat = point.latitude < minLat ? point.latitude : minLat;
        maxLat = point.latitude > maxLat ? point.latitude : maxLat;
        minLng = point.longitude < minLng ? point.longitude : minLng;
        maxLng = point.longitude > maxLng ? point.longitude : maxLng;
      }
    }

    // Ajouter un padding aux limites pour s'assurer que tous les secteurs sont entièrement visibles
    // avec une marge autour (5% de la taille totale)
    final latPadding = (maxLat - minLat) * 0.05;
    final lngPadding = (maxLng - minLng) * 0.05;

    minLat -= latPadding;
    maxLat += latPadding;
    minLng -= lngPadding;
    maxLng += lngPadding;

    // Calculer le centre
    final centerLat = (minLat + maxLat) / 2;
    final centerLng = (minLng + maxLng) / 2;

    // Calculer le zoom approprié en tenant compte des dimensions de l'écran
    final mapWidth = MediaQuery.of(context).size.width;
    final mapHeight = MediaQuery.of(context).size.height *
        0.7; // Estimation de la hauteur de la carte
    final zoom = _calculateOptimalZoom(
        minLat, maxLat, minLng, maxLng, mapWidth, mapHeight);

    // Centrer la carte sur ces limites avec animation
    _mapController.move(LatLng(centerLat, centerLng), zoom);

    // Mettre à jour l'état pour refléter la nouvelle position
    setState(() {
      _currentPosition = LatLng(centerLat, centerLng);
      _currentZoom = zoom;
    });

    debugPrint('Carte centrée sur tous les secteurs avec zoom: $zoom');
  }

  // Centrer la carte sur un secteur spécifique
  void _centerMapOnSpecificSector(int sectorId) {
    final sectorIndex = _sectors.indexWhere((s) => s['id'] == sectorId);
    if (sectorIndex == -1) return;

    // Mettre à jour le secteur sélectionné
    _selectedSectorId = sectorId;

    final sector = _sectors[sectorIndex];
    final points = sector['points'] as List<LatLng>;
    final sectorName = sector['name'] as String;

    debugPrint(
        'Centrage sur le secteur: $sectorName (ID: $sectorId) avec ${points.length} points');

    if (points.isEmpty) {
      debugPrint('Aucun point dans ce secteur!');
      return;
    }

    // Trouver les limites du secteur
    double minLat = 90.0;
    double maxLat = -90.0;
    double minLng = 180.0;
    double maxLng = -180.0;

    for (final point in points) {
      minLat = point.latitude < minLat ? point.latitude : minLat;
      maxLat = point.latitude > maxLat ? point.latitude : maxLat;
      minLng = point.longitude < minLng ? point.longitude : minLng;
      maxLng = point.longitude > maxLng ? point.longitude : maxLng;
    }

    debugPrint(
        'Limites du secteur: minLat=$minLat, maxLat=$maxLat, minLng=$minLng, maxLng=$maxLng');

    // Vérifier si les coordonnées sont valides
    if (minLat >= maxLat || minLng >= maxLng) {
      debugPrint('Coordonnées invalides pour le secteur $sectorName');
      return;
    }

    // Calculer la taille du secteur
    final latSpan = maxLat - minLat;
    final lngSpan = maxLng - minLng;
    debugPrint('Taille du secteur: latSpan=$latSpan, lngSpan=$lngSpan');

    // Ajouter un padding minimal aux limites pour s'assurer que le secteur est bien visible
    // mais prend le maximum de place sur la carte
    final double latPadding, lngPadding;
    if (latSpan < 0.01 || lngSpan < 0.01) {
      // Pour les très petits secteurs, utiliser un padding très réduit
      latPadding = 0.0003;
      lngPadding = 0.0003;
    } else if (latSpan < 0.05 || lngSpan < 0.05) {
      // Pour les petits secteurs, padding réduit
      latPadding = 0.0005;
      lngPadding = 0.0005;
    } else {
      // Pour les secteurs plus grands, utiliser un pourcentage minimal
      latPadding = latSpan * 0.03; // 3% au lieu de 10%
      lngPadding = lngSpan * 0.03;
    }

    minLat -= latPadding;
    maxLat += latPadding;
    minLng -= lngPadding;
    maxLng += lngPadding;

    debugPrint(
        'Limites avec padding: minLat=$minLat, maxLat=$maxLat, minLng=$minLng, maxLng=$maxLng');

    // Calculer le centre
    final centerLat = (minLat + maxLat) / 2;
    final centerLng = (minLng + maxLng) / 2;

    // Déterminer le zoom approprié en fonction de la taille du secteur
    double zoom;

    // Pour les très petits secteurs (comme des quartiers), utiliser un zoom fixe élevé
    if (latSpan < 0.01 && lngSpan < 0.01) {
      zoom = 16.0; // Zoom élevé pour les petits quartiers
    } else if (latSpan < 0.02 && lngSpan < 0.02) {
      zoom = 15.0; // Zoom élevé pour les petits quartiers
    } else if (latSpan < 0.05 && lngSpan < 0.05) {
      zoom =
          13.0; // Zoom pour les secteurs de taille moyenne (quelques quartiers)
    } else if (latSpan < 0.1 && lngSpan < 0.1) {
      zoom = 12.0; // Zoom pour les grands secteurs (ville)
    } else {
      // Pour les secteurs plus grands, calculer le zoom
      final mapWidth = MediaQuery.of(context).size.width;
      final mapHeight = MediaQuery.of(context).size.height * 0.7;
      zoom = _calculateOptimalZoom(
          minLat, maxLat, minLng, maxLng, mapWidth, mapHeight);
    }

    debugPrint('Zoom calculé pour le secteur $sectorName: $zoom');

    // Centrer la carte sur le secteur avec animation
    _mapController.move(LatLng(centerLat, centerLng), zoom);

    // Mettre à jour l'état pour refléter la nouvelle position
    setState(() {
      _currentPosition = LatLng(centerLat, centerLng);
      _currentZoom = zoom;
    });
  }

  // Calculer le zoom optimal pour afficher une zone géographique dans la fenêtre de la carte
  double _calculateOptimalZoom(double minLat, double maxLat, double minLng,
      double maxLng, double mapWidth, double mapHeight) {
    // Méthode simplifiée et plus fiable pour calculer le zoom

    // Vérifier si les coordonnées sont valides
    if (minLat >= maxLat || minLng >= maxLng) {
      debugPrint('Coordonnées invalides pour le calcul du zoom');
      return 12.0; // Valeur par défaut raisonnable
    }

    // Calculer la taille en degrés
    final latSpan = maxLat - minLat;
    final lngSpan = maxLng - minLng;

    debugPrint(
        '_calculateOptimalZoom - Taille: latSpan=$latSpan, lngSpan=$lngSpan');

    // Ajouter un facteur de sécurité pour éviter les divisions par zéro
    if (latSpan < 0.0000001 || lngSpan < 0.0000001) {
      return 15.0; // Zoom élevé pour un point très précis
    }

    // Formule simplifiée pour le calcul du zoom
    // Basée sur l'expérience et adaptée pour les petites zones
    double zoom;

    if (latSpan < 0.005 || lngSpan < 0.005) {
      // Très petite zone (quartier)
      zoom = 16.0;
    } else if (latSpan < 0.01 || lngSpan < 0.01) {
      // Petite zone (quartier)
      zoom = 15.0;
    } else if (latSpan < 0.02 || lngSpan < 0.02) {
      // Petite zone (plusieurs quartiers)
      zoom = 14.0;
    } else if (latSpan < 0.05 || lngSpan < 0.05) {
      // Zone moyenne (ville)
      zoom = 13.0;
    } else if (latSpan < 0.2 || lngSpan < 0.2) {
      // Grande zone (agglomération)
      zoom = 11.0;
    } else if (latSpan < 0.5 || lngSpan < 0.5) {
      // Très grande zone (département)
      zoom = 9.0;
    } else if (latSpan < 2.0 || lngSpan < 2.0) {
      // Région
      zoom = 7.0;
    } else if (latSpan < 5.0 || lngSpan < 5.0) {
      // Pays
      zoom = 5.0;
    } else {
      // Continent ou plus
      zoom = 3.0;
    }

    debugPrint('Zoom calculé: $zoom pour zone: lat $latSpan, lng $lngSpan');
    return zoom;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final size = MediaQuery.of(context).size;
    final isDesktop = size.width > 900;

    return Scaffold(
      backgroundColor: Colors.transparent,
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // En-tête - affiché uniquement si pas en plein écran
            if (!_isFullScreen)
              Padding(
                padding: const EdgeInsets.all(16.0),
                child: Text(
                  'Carte des passages',
                  style: theme.textTheme.headlineMedium?.copyWith(
                    fontWeight: FontWeight.bold,
                    color: theme.colorScheme.primary,
                  ),
                ),
              ),

            // Filtres - affichés uniquement si pas en plein écran
            if (!_isFullScreen) _buildFilters(theme, isDesktop),

            // Carte
            Expanded(
              child: Stack(
                children: [
                  // Carte principale utilisant le widget commun MapboxMap
                  MapboxMap(
                    initialPosition: _currentPosition,
                    initialZoom: _currentZoom,
                    mapController: _mapController,
                    markers: _buildPassageMarkers(),
                    polygons: _buildSectorPolygons(),
                    showControls: true,
                    onMapEvent: (event) {
                      if (event is MapEventMove) {
                        // Mettre à jour la position et le zoom actuels
                        setState(() {
                          _currentPosition = event.camera.center;
                          _currentZoom = event.camera.zoom;
                        });
                      }
                    },
                  ),

                  // Combobox de sélection de secteurs (si plus d'un secteur)
                  if (_shouldShowSectorCombobox)
                    Positioned(
                      left: 16.0,
                      top: 16.0,
                      child: Material(
                        elevation: 4,
                        borderRadius: BorderRadius.circular(8),
                        child: Container(
                          padding: const EdgeInsets.symmetric(
                              horizontal: 12, vertical: 4),
                          width:
                              220, // Largeur fixe pour accommoder les noms longs
                          decoration: BoxDecoration(
                            color: Colors.white.withOpacity(0.95),
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: Row(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Icon(Icons.location_on,
                                  size: 18, color: Colors.blue),
                              const SizedBox(width: 8),
                              Expanded(
                                child: DropdownButton<int?>(
                                  value: _selectedSectorId,
                                  hint: const Text('Tous les secteurs'),
                                  isExpanded: true,
                                  underline:
                                      Container(), // Supprimer la ligne sous le dropdown
                                  icon: Icon(Icons.arrow_drop_down,
                                      color: Colors.blue),
                                  items: _sectorItems,
                                  onChanged: (int? sectorId) {
                                    setState(() {
                                      _selectedSectorId = sectorId;
                                    });

                                    if (sectorId != null) {
                                      _centerMapOnSpecificSector(sectorId);
                                    } else {
                                      // Si "Tous les secteurs" est sélectionné
                                      _centerMapOnSectors();
                                      // Recharger tous les passages sans filtrage par secteur
                                      _loadPassages();
                                    }
                                  },
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),

                  // Bouton de plein écran (les autres contrôles sont gérés par MapboxMap)
                  Positioned(
                    bottom: 16.0,
                    right: 16.0,
                    child: _buildMapButton(
                      icon: _isFullScreen
                          ? Icons.fullscreen_exit
                          : Icons.fullscreen,
                      onPressed: () {
                        setState(() {
                          _isFullScreen = !_isFullScreen;
                        });
                      },
                    ),
                  ),

                  // Bouton de localisation personnalisé (pour utiliser notre propre logique)
                  Positioned(
                    bottom: 80.0, // Positionné au-dessus du bouton plein écran
                    right: 16.0,
                    child: _buildMapButton(
                      icon: Icons.my_location,
                      onPressed: () {
                        _getUserLocation();
                      },
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  // Construire les filtres pour les passages
  Widget _buildFilters(ThemeData theme, bool isDesktop) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Wrap(
            spacing: 8.0,
            runSpacing: 8.0,
            children: [
              // Filtre pour les passages effectués
              _buildFilterChip(
                label: AppKeys.typesPassages[1]?['titres'] as String? ??
                    'Effectués',
                selected: _showEffectues,
                color: Color(AppKeys.typesPassages[1]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showEffectues = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),

              // Filtre pour les passages à finaliser
              _buildFilterChip(
                label: AppKeys.typesPassages[2]?['titres'] as String? ??
                    'À finaliser',
                selected: _showAFinaliser,
                color: Color(AppKeys.typesPassages[2]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showAFinaliser = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),

              // Filtre pour les passages refusés
              _buildFilterChip(
                label:
                    AppKeys.typesPassages[3]?['titres'] as String? ?? 'Refusés',
                selected: _showRefuses,
                color: Color(AppKeys.typesPassages[3]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showRefuses = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),

              // Filtre pour les dons
              _buildFilterChip(
                label: AppKeys.typesPassages[4]?['titres'] as String? ?? 'Dons',
                selected: _showDons,
                color: Color(AppKeys.typesPassages[4]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showDons = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),

              // Filtre pour les lots
              _buildFilterChip(
                label: AppKeys.typesPassages[5]?['titres'] as String? ?? 'Lots',
                selected: _showLots,
                color: Color(AppKeys.typesPassages[5]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showLots = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),

              // Filtre pour les maisons vides
              _buildFilterChip(
                label: AppKeys.typesPassages[6]?['titres'] as String? ??
                    'Maisons vides',
                selected: _showMaisonsVides,
                color: Color(AppKeys.typesPassages[6]?['couleur2'] as int),
                onSelected: (selected) {
                  setState(() {
                    _showMaisonsVides = selected;
                    _loadPassages(); // Recharger les passages avec le nouveau filtre
                    _saveSettings(); // Sauvegarder les préférences
                  });
                },
              ),
            ],
          ),
        ],
      ),
    );
  }

  // Construire un chip de filtre
  Widget _buildFilterChip({
    required String label,
    required bool selected,
    required Color color,
    required Function(bool) onSelected,
  }) {
    // Utiliser la couleur vive pour les boutons sélectionnés et une version plus terne pour les désélectionnés
    final Color avatarColor = selected ? color : color.withOpacity(0.4);
    final Color chipColor =
        selected ? color.withOpacity(0.2) : Colors.grey.withOpacity(0.1);

    return FilterChip(
      label: Text(
        label,
        style: TextStyle(
          fontWeight: selected ? FontWeight.bold : FontWeight.normal,
          color: selected ? Colors.black : Colors.black54,
        ),
      ),
      selected: selected,
      showCheckmark: false,
      avatar: CircleAvatar(
        backgroundColor: avatarColor,
        radius: 10.0,
      ),
      backgroundColor: Colors.white,
      selectedColor: chipColor,
      side: BorderSide(
        color: selected ? color : Colors.grey.withOpacity(0.3),
        width: selected ? 1.5 : 1.0,
      ),
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
      onSelected: onSelected,
    );
  }

  // Construction d'un bouton de carte personnalisé
  Widget _buildMapButton({
    required IconData icon,
    required VoidCallback onPressed,
  }) {
    return Container(
      width: 40,
      height: 40,
      decoration: BoxDecoration(
        color: Colors.white,
        shape: BoxShape.circle,
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.2),
            blurRadius: 6,
            offset: const Offset(0, 3),
          ),
        ],
      ),
      child: IconButton(
        icon: Icon(icon, size: 20),
        onPressed: onPressed,
        padding: EdgeInsets.zero,
        constraints: const BoxConstraints(),
        color: Colors.blue,
      ),
    );
  }

  // Construire les marqueurs pour les passages
  List<Marker> _buildPassageMarkers() {
    return _passages.map((passage) {
      return Marker(
        point: passage['position'] as LatLng,
        width: 14.0,
        height: 14.0,
        child: GestureDetector(
          onTap: () {
            _showPassageInfo(passage);
          },
          child: Container(
            decoration: BoxDecoration(
              color: passage['color'] as Color,
              shape: BoxShape.circle,
              border: Border.all(
                color: Colors.white,
                width: 1.0,
              ),
            ),
          ),
        ),
      );
    }).toList();
  }

  // Construire les polygones pour les secteurs
  List<Polygon> _buildSectorPolygons() {
    return _sectors.map((sector) {
      return Polygon(
        points: sector['points'] as List<LatLng>,
        color: (sector['color'] as Color).withOpacity(0.3),
        borderColor: (sector['color'] as Color).withOpacity(1.0),
        borderStrokeWidth: 2.0,
      );
    }).toList();
  }

  // Méthode pour mettre à jour la position sur la carte
  void _updateMapPosition(LatLng position, {double? zoom}) {
    _mapController.move(
      position,
      zoom ?? _mapController.camera.zoom,
    );

    // Mettre à jour les variables d'état
    setState(() {
      _currentPosition = position;
      if (zoom != null) {
        _currentZoom = zoom;
      }
    });

    // Sauvegarder les paramètres après mise à jour de la position
    _saveSettings();
  }

  // Afficher les informations d'un passage lorsqu'on clique dessus
  void _showPassageInfo(Map<String, dynamic> passage) {
    final PassageModel passageModel = passage['model'] as PassageModel;
    final int type = passageModel.fkType;

    // Construire l'adresse complète
    final String adresse =
        '${passageModel.numero}, ${passageModel.rueBis} ${passageModel.rue}';

    // Informations sur l'étage, l'appartement et la résidence (si habitat = 2)
    String? etageInfo;
    String? apptInfo;
    String? residenceInfo;
    if (passageModel.fkHabitat == 2) {
      if (passageModel.niveau.isNotEmpty) {
        etageInfo = 'Etage ${passageModel.niveau}';
      }
      if (passageModel.appt.isNotEmpty) {
        apptInfo = 'appt. ${passageModel.appt}';
      }
      if (passageModel.residence.isNotEmpty) {
        residenceInfo = passageModel.residence;
      }
    }

    // Formater la date (uniquement si le type n'est pas 2)
    String dateInfo = '';
    if (type != 2) {
      dateInfo = 'Date: ${_formatDate(passageModel.passedAt)}';
    }

    // Récupérer le nom du passage (si le type n'est pas 6 - Maison vide)
    String? nomInfo;
    if (type != 6 && passageModel.name.isNotEmpty) {
      nomInfo = passageModel.name;
    }

    // Récupérer les informations de règlement si le type est 1 (Effectué) ou 5 (Lot)
    Widget? reglementInfo;
    if (type == 1 || type == 5) {
      final int typeReglementId = passageModel.fkTypeReglement;
      final String montant = passageModel.montant;

      // Récupérer les informations du type de règlement
      if (AppKeys.typesReglements.containsKey(typeReglementId)) {
        final Map<String, dynamic> typeReglement =
            AppKeys.typesReglements[typeReglementId]!;
        final String titre = typeReglement['titre'] as String;
        final Color couleur = Color(typeReglement['couleur'] as int);
        final IconData iconData = typeReglement['icon_data'] as IconData;

        reglementInfo = Padding(
          padding: const EdgeInsets.only(top: 8.0),
          child: Row(
            children: [
              Icon(iconData, color: couleur, size: 20),
              const SizedBox(width: 8),
              Text('$titre: $montant €',
                  style:
                      TextStyle(color: couleur, fontWeight: FontWeight.bold)),
            ],
          ),
        );
      }
    }

    // Afficher une bulle d'information
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        contentPadding: const EdgeInsets.fromLTRB(24, 20, 24, 0),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Adresse: $adresse'),
            if (residenceInfo != null) ...[
              const SizedBox(height: 4),
              Text(residenceInfo)
            ],
            if (etageInfo != null) ...[
              const SizedBox(height: 4),
              Text(etageInfo)
            ],
            if (apptInfo != null) ...[
              const SizedBox(height: 4),
              Text(apptInfo)
            ],
            if (dateInfo.isNotEmpty) ...[
              const SizedBox(height: 8),
              Text(dateInfo)
            ],
            if (nomInfo != null) ...[
              const SizedBox(height: 8),
              Text('Nom: $nomInfo')
            ],
            if (reglementInfo != null) reglementInfo,
          ],
        ),
        actionsPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
        actions: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Row(
                children: [
                  // Bouton d'édition
                  IconButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                      // Logique pour éditer le passage
                      debugPrint('Éditer le passage ${passageModel.id}');
                    },
                    icon: const Icon(Icons.edit),
                    color: Colors.blue,
                    tooltip: 'Modifier',
                  ),

                  // Bouton de suppression
                  IconButton(
                    onPressed: () {
                      Navigator.of(context).pop();
                      // Logique pour supprimer le passage
                      debugPrint('Supprimer le passage ${passageModel.id}');
                    },
                    icon: const Icon(Icons.delete),
                    color: Colors.red,
                    tooltip: 'Supprimer',
                  ),
                ],
              ),

              // Bouton de fermeture
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: const Text('Fermer'),
              ),
            ],
          ),
        ],
      ),
    );
  }

  // Formater une date
  String _formatDate(DateTime date) {
    return '${date.day.toString().padLeft(2, '0')}/${date.month.toString().padLeft(2, '0')}/${date.year}';
  }
}
