import 'package:flutter/material.dart';
import 'package:geosector_app/core/data/models/sector_model.dart';
import 'package:geosector_app/core/data/models/membre_model.dart';
import 'package:geosector_app/core/data/models/user_sector_model.dart';
import 'package:geosector_app/core/services/current_amicale_service.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/constants/app_keys.dart';

class SectorDialog extends StatefulWidget {
  final SectorModel? existingSector;
  final List<List<double>> coordinates;
  final Future<void> Function(String name, String color, List<int> memberIds, bool updatePassages) onSave;

  const SectorDialog({
    super.key,
    this.existingSector,
    required this.coordinates,
    required this.onSave,
  });

  @override
  State<SectorDialog> createState() => _SectorDialogState();
}

class _SectorDialogState extends State<SectorDialog> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _nameFocusNode = FocusNode();
  final _searchController = TextEditingController();
  Color _selectedColor = Colors.blue;
  final List<int> _selectedMemberIds = [];
  bool _isLoading = false;
  String _searchQuery = '';
  bool _updatePassages = true; // Par défaut activé
  bool _initialUpdatePassages = true; // Valeur initiale pour détecter les changements

  @override
  void initState() {
    super.initState();
    if (widget.existingSector != null) {
      _nameController.text = widget.existingSector!.libelle;
      _selectedColor = _hexToColor(widget.existingSector!.color);
      // Charger les membres affectés au secteur
      _loadSectorMembers();
    }
    
    // Donner le focus au champ nom après que le dialog soit construit
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _nameFocusNode.requestFocus();
    });
  }
  
  // Charger les membres actuellement affectés au secteur
  void _loadSectorMembers() {
    if (widget.existingSector == null) return;
    
    debugPrint('=== Début chargement membres pour secteur ${widget.existingSector!.id} - ${widget.existingSector!.libelle} ===');
    
    try {
      // Vérifier si la box UserSector est ouverte
      if (!Hive.isBoxOpen(AppKeys.userSectorBoxName)) {
        debugPrint('Box UserSector non ouverte');
        return;
      }
      
      final userSectorBox = Hive.box<UserSectorModel>(AppKeys.userSectorBoxName);
      debugPrint('Box UserSector contient ${userSectorBox.length} entrées au total');
      
      // Afficher toutes les entrées pour debug
      for (var i = 0; i < userSectorBox.length; i++) {
        final us = userSectorBox.getAt(i);
        if (us != null) {
          debugPrint('  - UserSector[$i]: userId=${us.userId}, opeUserId=${us.opeUserId}, fkSector=${us.fkSector}, name="${us.firstName} ${us.name}"');
        }
      }

      // Récupérer tous les UserSectorModel pour ce secteur
      final userSectors = userSectorBox.values
          .where((us) => us.fkSector == widget.existingSector!.id)
          .toList();

      debugPrint('Trouvé ${userSectors.length} UserSectorModel pour le secteur ${widget.existingSector!.id}');

      // Pré-sélectionner les IDs des membres affectés (ope_users.id)
      setState(() {
        _selectedMemberIds.clear();
        for (final userSector in userSectors) {
          // Utiliser opeUserId (ope_users.id) pour la sélection
          _selectedMemberIds.add(userSector.opeUserId);
          debugPrint('Membre présélectionné: ${userSector.firstName} ${userSector.name} (userId: ${userSector.userId}, opeUserId: ${userSector.opeUserId}, fkSector: ${userSector.fkSector})');
        }
      });
      
      debugPrint('=== Fin chargement: ${_selectedMemberIds.length} membres présélectionnés ===');
      debugPrint('IDs présélectionnés: $_selectedMemberIds');
      
      // Marquer le chargement comme terminé
      setState(() {
      });
    } catch (e) {
      debugPrint('Erreur lors du chargement des membres du secteur: $e');
      setState(() {
        // Marquer comme terminé même en cas d'erreur
      });
    }
  }

  @override
  void dispose() {
    _nameController.dispose();
    _nameFocusNode.dispose();
    _searchController.dispose();
    super.dispose();
  }

  Color _hexToColor(String hexColor) {
    final String colorStr = hexColor.startsWith('#') ? hexColor.substring(1) : hexColor;
    final String fullColorStr = colorStr.length == 6 ? 'FF$colorStr' : colorStr;
    return Color(int.parse(fullColorStr, radix: 16));
  }

  String _colorToHex(Color color) {
    return '#${color.value.toRadixString(16).substring(2).toUpperCase()}';
  }

  // Dialogue de confirmation pour le changement du switch
  Future<bool> _showUpdatePassagesConfirmation(bool newValue) async {
    final result = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: Row(
          children: [
            Icon(
              Icons.warning_amber_rounded,
              color: Colors.orange,
              size: 28,
            ),
            const SizedBox(width: 8),
            const Text('Confirmation'),
          ],
        ),
        content: Text(
          newValue
              ? 'Êtes-vous sûr de vouloir recalculer les passages ?\n\n'
                'Tous les passages du secteur seront réaffectés selon les nouvelles limites.'
              : 'Êtes-vous sûr de vouloir conserver les passages existants ?\n\n'
                'Les passages actuels ne seront pas modifiés même si les limites du secteur changent.',
          style: const TextStyle(fontSize: 15),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('Annuler'),
          ),
          ElevatedButton(
            onPressed: () => Navigator.of(context).pop(true),
            style: ElevatedButton.styleFrom(
              backgroundColor: Colors.blue,
              foregroundColor: Colors.white,
            ),
            child: const Text('Confirmer'),
          ),
        ],
      ),
    );

    return result ?? false;
  }

  void _handleSave() async {
    if (_formKey.currentState!.validate()) {
      // Vérifier qu'au moins un membre est sélectionné
      if (_selectedMemberIds.isEmpty) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Veuillez sélectionner au moins un membre'),
            backgroundColor: Colors.orange,
            duration: Duration(seconds: 3),
          ),
        );
        return;
      }
      
      // Indiquer que nous sommes en train de sauvegarder
      setState(() => _isLoading = true);
      
      try {
        // Appeler le callback onSave et attendre sa résolution
        await widget.onSave(
          _nameController.text.trim(),
          _colorToHex(_selectedColor),
          _selectedMemberIds,
          _updatePassages, // Passer le paramètre updatePassages
        );
        
        // Si tout s'est bien passé, fermer le dialog
        if (mounted) {
          Navigator.of(context).pop();
        }
      } catch (e) {
        // En cas d'erreur, réactiver le bouton
        if (mounted) {
          setState(() => _isLoading = false);
        }
        // L'erreur sera gérée par le callback onSave
        rethrow;
      }
    }
  }

  void _showColorPicker() {
    // Grille 6x6 de couleurs suivant le spectre
    // 6 colonnes: Rouge, Orange, Jaune, Vert, Bleu, Violet
    // 6 lignes: variations de luminosité/saturation
    final List<Color> colors = _generateSpectralColorGrid();

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Choisir une couleur'),
        contentPadding: const EdgeInsets.fromLTRB(20, 12, 20, 20),
        content: Container(
          width: 280, // Largeur fixe pour contrôler la taille
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const SizedBox(height: 8),
              Container(
                padding: const EdgeInsets.all(8),
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade300),
                  borderRadius: BorderRadius.circular(8),
                  color: Colors.grey.shade50,
                ),
                child: GridView.builder(
                  shrinkWrap: true,
                  physics: const NeverScrollableScrollPhysics(),
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 6,
                    mainAxisSpacing: 4,
                    crossAxisSpacing: 4,
                    childAspectRatio: 1.0,
                  ),
                  itemCount: colors.length,
                  itemBuilder: (context, index) {
                    final color = colors[index];
                    final isSelected = _selectedColor.value == color.value;

                    return InkWell(
                      onTap: () {
                        setState(() {
                          _selectedColor = color;
                        });
                        Navigator.of(context).pop();
                      },
                      child: Container(
                        width: 35,
                        height: 35,
                        decoration: BoxDecoration(
                          color: color,
                          borderRadius: BorderRadius.circular(4),
                          border: Border.all(
                            color: isSelected ? Colors.black87 : Colors.grey.shade400,
                            width: isSelected ? 2.5 : 0.5,
                          ),
                          boxShadow: isSelected
                              ? [
                                  BoxShadow(
                                    color: Colors.black.withOpacity(0.3),
                                    blurRadius: 4,
                                    offset: const Offset(0, 2),
                                  ),
                                ]
                              : null,
                        ),
                        child: isSelected
                            ? const Icon(
                                Icons.check,
                                color: Colors.white,
                                size: 18,
                                shadows: [
                                  Shadow(
                                    color: Colors.black,
                                    blurRadius: 2,
                                  ),
                                ],
                              )
                            : null,
                      ),
                    );
                  },
                ),
              ),
              const SizedBox(height: 12),
              // Affichage de la couleur sélectionnée
              Container(
                height: 40,
                decoration: BoxDecoration(
                  color: _selectedColor,
                  borderRadius: BorderRadius.circular(6),
                  border: Border.all(color: Colors.grey.shade400),
                ),
                child: Center(
                  child: Text(
                    'Couleur sélectionnée',
                    style: TextStyle(
                      color: _selectedColor.computeLuminance() > 0.5
                          ? Colors.black87
                          : Colors.white,
                      fontWeight: FontWeight.w500,
                      fontSize: 13,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Annuler'),
          ),
        ],
      ),
    );
  }

  // Mettre en surbrillance les termes recherchés dans le texte
  List<TextSpan> _highlightSearchTerms(String text) {
    if (_searchQuery.isEmpty) {
      return [TextSpan(text: text)];
    }
    
    final List<TextSpan> spans = [];
    final lowerText = text.toLowerCase();
    int start = 0;
    int index = lowerText.indexOf(_searchQuery, start);
    
    while (index != -1) {
      // Ajouter le texte avant le terme trouvé
      if (index > start) {
        spans.add(TextSpan(
          text: text.substring(start, index),
        ));
      }
      
      // Ajouter le terme trouvé en surbrillance
      spans.add(TextSpan(
        text: text.substring(index, index + _searchQuery.length),
        style: const TextStyle(
          backgroundColor: Colors.yellow,
          fontWeight: FontWeight.bold,
        ),
      ));
      
      start = index + _searchQuery.length;
      index = lowerText.indexOf(_searchQuery, start);
    }
    
    // Ajouter le reste du texte
    if (start < text.length) {
      spans.add(TextSpan(
        text: text.substring(start),
      ));
    }
    
    return spans;
  }

  // Générer une grille 6x6 de couleurs spectrales
  List<Color> _generateSpectralColorGrid() {
    final List<Color> colors = [];
    
    // 6 teintes de base (colonnes)
    final List<double> hues = [
      0,    // Rouge
      30,   // Orange
      60,   // Jaune
      120,  // Vert
      210,  // Bleu
      270,  // Violet
    ];
    
    // 6 variations de luminosité/saturation (lignes)
    // Du plus clair au plus foncé
    final List<Map<String, double>> variations = [
      {'saturation': 0.3, 'lightness': 0.85},  // Très clair
      {'saturation': 0.5, 'lightness': 0.70},  // Clair
      {'saturation': 0.7, 'lightness': 0.55},  // Moyen clair
      {'saturation': 0.85, 'lightness': 0.45}, // Moyen foncé
      {'saturation': 0.95, 'lightness': 0.35}, // Foncé
      {'saturation': 1.0, 'lightness': 0.25},  // Très foncé
    ];
    
    // Générer la grille ligne par ligne
    for (final variation in variations) {
      for (final hue in hues) {
        colors.add(
          HSLColor.fromAHSL(
            1.0,
            hue,
            variation['saturation']!,
            variation['lightness']!,
          ).toColor(),
        );
      }
    }
    
    return colors;
  }

  @override
  Widget build(BuildContext context) {
    final currentAmicale = CurrentAmicaleService.instance.currentAmicale;
    final screenHeight = MediaQuery.of(context).size.height;
    final dialogHeight = (screenHeight * 0.8).clamp(0.0, 800.0); // 80% de l'écran avec max 800px
    
    return AlertDialog(
      title: Text(widget.existingSector == null ? 'Nouveau secteur' : 'Modifier le secteur'),
      content: Container(
        width: 450, // Largeur fixe pour la dialog
        height: dialogHeight, // Hauteur avec maximum de 800px
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Section scrollable pour nom et couleur
              // Nom du secteur
              TextFormField(
                controller: _nameController,
                focusNode: _nameFocusNode,
                decoration: InputDecoration(
                  labelText: 'Nom du secteur',
                  labelStyle: TextStyle(color: Colors.black),
                  label: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Text('Nom du secteur'),
                      Text(
                        ' *',
                        style: TextStyle(color: Colors.red),
                      ),
                    ],
                  ),
                  hintText: 'Ex: Centre-ville',
                  prefixIcon: Icon(Icons.location_on),
                ),
                validator: (value) {
                  if (value == null || value.trim().isEmpty) {
                    return 'Veuillez entrer un nom';
                  }
                  return null;
                },
              ),
              const SizedBox(height: 20),

              // Couleur du secteur
              const Text(
                'Couleur du secteur',
                style: TextStyle(fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 10),
              InkWell(
                onTap: () {
                  _showColorPicker();
                },
                child: Container(
                  height: 50,
                  decoration: BoxDecoration(
                    color: _selectedColor,
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(color: Colors.grey),
                  ),
                  child: Center(
                    child: Text(
                      'Toucher pour changer',
                      style: TextStyle(
                        color: _selectedColor.computeLuminance() > 0.5
                            ? Colors.black
                            : Colors.white,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 20),

              // Switch pour la mise à jour des passages (uniquement en mode édition)
              if (widget.existingSector != null) ...[
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
                  decoration: BoxDecoration(
                    color: Colors.blue.shade50,
                    borderRadius: BorderRadius.circular(8),
                    border: Border.all(color: Colors.blue.shade200),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Expanded(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  'Mise à jour des passages',
                                  style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 15,
                                    color: Colors.blue.shade900,
                                  ),
                                ),
                                const SizedBox(height: 4),
                                Text(
                                  _updatePassages
                                      ? 'Les passages seront recalculés et réaffectés'
                                      : 'Les passages existants ne seront pas modifiés',
                                  style: TextStyle(
                                    fontSize: 12,
                                    color: Colors.grey.shade700,
                                    fontStyle: FontStyle.italic,
                                  ),
                                ),
                              ],
                            ),
                          ),
                          Switch(
                            value: _updatePassages,
                            onChanged: (value) async {
                              // Afficher confirmation uniquement si la valeur change par rapport à l'initiale
                              if (value != _initialUpdatePassages) {
                                final confirmed = await _showUpdatePassagesConfirmation(value);
                                if (confirmed) {
                                  setState(() {
                                    _updatePassages = value;
                                  });
                                }
                              } else {
                                setState(() {
                                  _updatePassages = value;
                                });
                              }
                            },
                            activeColor: Colors.blue,
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 20),
              ],

              // Sélection des membres
              Row(
                children: [
                  const Text(
                    'Membres affectés',
                    style: TextStyle(fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(width: 4),
                  Text(
                    '*',
                    style: TextStyle(
                      color: Colors.red,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 10),
              
              // Champ de recherche pour filtrer les membres
              TextField(
                controller: _searchController,
                decoration: InputDecoration(
                  hintText: 'Rechercher par prénom, nom ou nom de tournée...',
                  prefixIcon: const Icon(Icons.search),
                  suffixIcon: _searchQuery.isNotEmpty
                      ? IconButton(
                          icon: const Icon(Icons.clear),
                          onPressed: () {
                            setState(() {
                              _searchController.clear();
                              _searchQuery = '';
                            });
                          },
                        )
                      : null,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(8),
                  ),
                  contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                ),
                onChanged: (value) {
                  setState(() {
                    _searchQuery = value.toLowerCase();
                  });
                },
              ),
              const SizedBox(height: 10),
              
              if (_selectedMemberIds.isEmpty)
                Padding(
                  padding: const EdgeInsets.only(bottom: 8.0),
                  child: Text(
                    'Sélectionnez au moins un membre',
                    style: TextStyle(
                      fontSize: 12,
                      color: Colors.grey[600],
                      fontStyle: FontStyle.italic,
                    ),
                  ),
                ),
                
              // Liste des membres avec scrolling et filtre
              if (currentAmicale != null)
                Expanded(
                  child: ValueListenableBuilder<Box<MembreModel>>(
                    valueListenable: Hive.box<MembreModel>(AppKeys.membresBoxName).listenable(),
                    builder: (context, box, _) {
                      debugPrint('=== Build liste membres - IDs présélectionnés: $_selectedMemberIds ===');

                      // Récupérer tous les membres (déjà uniques dans la box)
                      // Filtrer uniquement ceux qui ont un opeUserId (dans l'opération courante)
                      var membres = box.values
                          .whereType<MembreModel>()
                          .where((membre) => membre.opeUserId != null)
                          .toList();

                      // Appliquer le filtre de recherche
                      if (_searchQuery.isNotEmpty) {
                        membres = membres.where((membre) {
                          final firstName = membre.firstName?.toLowerCase() ?? '';
                          final lastName = membre.name?.toLowerCase() ?? '';
                          final sectName = membre.sectName?.toLowerCase() ?? '';

                          return firstName.contains(_searchQuery) ||
                                 lastName.contains(_searchQuery) ||
                                 sectName.contains(_searchQuery);
                        }).toList();
                      }

                      // Trier : membres affectés en premier, puis les autres
                      membres.sort((a, b) {
                        final aSelected = _selectedMemberIds.contains(a.opeUserId);
                        final bSelected = _selectedMemberIds.contains(b.opeUserId);

                        // Si l'un est sélectionné et pas l'autre, le mettre en premier
                        if (aSelected && !bSelected) return -1;
                        if (!aSelected && bSelected) return 1;

                        // Sinon, trier alphabétiquement par prénom puis nom
                        final firstNameCompare = (a.firstName ?? '').compareTo(b.firstName ?? '');
                        if (firstNameCompare != 0) return firstNameCompare;
                        return (a.name ?? '').compareTo(b.name ?? '');
                      });

                      if (membres.isEmpty) {
                        return Center(
                          child: Padding(
                            padding: const EdgeInsets.all(20.0),
                            child: Text(
                              _searchQuery.isNotEmpty
                                  ? 'Aucun membre trouvé pour "$_searchQuery"'
                                  : 'Aucun membre disponible pour cette opération',
                              style: TextStyle(
                                color: Colors.grey[600],
                                fontSize: 14,
                              ),
                            ),
                          ),
                        );
                      }

                      // Afficher le nombre de résultats
                      return Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Padding(
                            padding: const EdgeInsets.symmetric(vertical: 4.0),
                            child: Text(
                              '${membres.length} membre${membres.length > 1 ? 's' : ''} ${_searchQuery.isNotEmpty ? 'trouvé${membres.length > 1 ? 's' : ''}' : 'disponible${membres.length > 1 ? 's' : ''}'}',
                              style: TextStyle(
                                fontSize: 12,
                                color: Colors.grey[700],
                              ),
                            ),
                          ),
                          Expanded(
                            child: Container(
                              decoration: BoxDecoration(
                                border: Border.all(color: Colors.grey),
                                borderRadius: BorderRadius.circular(8),
                              ),
                              child: ListView.builder(
                                itemCount: membres.length,
                                itemBuilder: (context, index) {
                                  final membre = membres[index];
                                  final isSelected = _selectedMemberIds.contains(membre.opeUserId);

                                  // Log pour debug
                                  if (index < 3) { // Limiter les logs aux 3 premiers membres
                                    debugPrint('Membre ${index}: ${membre.firstName} ${membre.name} (userId: ${membre.id}, opeUserId: ${membre.opeUserId}) - isSelected: $isSelected');
                                  }

                                  return CheckboxListTile(
                                    dense: true,
                                    contentPadding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 0.0),
                                    title: RichText(
                                      text: TextSpan(
                                        style: const TextStyle(fontSize: 14, color: Colors.black87),
                                        children: _highlightSearchTerms(
                                          '${membre.firstName} ${membre.name}${membre.sectName != null && membre.sectName!.isNotEmpty ? ' (${membre.sectName})' : ''}',
                                        ),
                                      ),
                                    ),
                                    value: isSelected,
                                    onChanged: (bool? value) {
                                      setState(() {
                                        if (value == true) {
                                          // opeUserId ne peut pas être null grâce au filtre ligne 517
                                          _selectedMemberIds.add(membre.opeUserId!);
                                        } else {
                                          _selectedMemberIds.remove(membre.opeUserId!);
                                        }
                                      });
                                    },
                                  );
                                },
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: _isLoading ? null : () => Navigator.of(context).pop(),
          child: const Text('Annuler'),
        ),
        ElevatedButton(
          onPressed: _isLoading ? null : _handleSave,
          child: _isLoading
              ? const SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(strokeWidth: 2),
                )
              : Text(widget.existingSector == null ? 'Créer' : 'Modifier'),
        ),
      ],
    );
  }
}