import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
import 'package:geosector_app/core/constants/app_keys.dart';
import 'package:geosector_app/core/data/models/pending_request.dart';
import 'package:geosector_app/core/services/api_service.dart';

/// Widget qui affiche l'état de la connexion Internet et le nombre de requêtes en attente
class ConnectivityIndicator extends StatefulWidget {
  /// Si true, affiche un message d'erreur lorsque l'appareil est déconnecté
  final bool showErrorMessage;

  /// Si true, affiche un badge avec le type de connexion (WiFi, données mobiles)
  final bool showConnectionType;

  /// Callback appelé lorsque l'état de la connexion change
  final Function(bool isConnected)? onConnectivityChanged;

  const ConnectivityIndicator({
    super.key,
    this.showErrorMessage = true,
    this.showConnectionType = true,
    this.onConnectivityChanged,
  });

  @override
  State<ConnectivityIndicator> createState() => _ConnectivityIndicatorState();
}

class _ConnectivityIndicatorState extends State<ConnectivityIndicator>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    // Configuration de l'animation de clignotement
    _animationController = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    );
    
    _animation = Tween<double>(
      begin: 1.0,
      end: 0.3,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    ));
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  void _updateAnimation(int pendingCount) {
    if (pendingCount > 0) {
      // Démarrer l'animation de clignotement si des requêtes sont en attente
      if (!_animationController.isAnimating) {
        _animationController.repeat(reverse: true);
      }
    } else {
      // Arrêter l'animation quand il n'y a plus de requêtes
      _animationController.stop();
      _animationController.value = 1.0;
    }
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    // Utiliser l'instance globale de connectivityService définie dans app.dart
    final isConnected = connectivityService.isConnected;
    final connectionType = connectivityService.connectionType;
    final connectionStatus = connectivityService.connectionStatus;

    // Appeler le callback si fourni, mais pas directement dans le build
    // pour éviter les problèmes de rendu
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (widget.onConnectivityChanged != null) {
        widget.onConnectivityChanged!(isConnected);
      }
    });

    // Vérifier si la box des requêtes en attente est ouverte
    if (!Hive.isBoxOpen(AppKeys.pendingRequestsBoxName)) {
      return _buildBasicIndicator(context, isConnected, connectionType, connectionStatus, theme, 0);
    }

    // Utiliser ValueListenableBuilder pour surveiller les requêtes en attente
    return ValueListenableBuilder<Box<PendingRequest>>(
      valueListenable: Hive.box<PendingRequest>(AppKeys.pendingRequestsBoxName).listenable(),
      builder: (context, box, child) {
        final pendingCount = box.length;
        
        // Mettre à jour l'animation en fonction du nombre de requêtes
        _updateAnimation(pendingCount);
        
        if (!isConnected && widget.showErrorMessage) {
          return Container(
            padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
            margin: const EdgeInsets.only(bottom: 8),
            decoration: BoxDecoration(
              color: theme.colorScheme.error.withOpacity(0.1),
              borderRadius: BorderRadius.circular(8),
              border: Border.all(
                color: theme.colorScheme.error.withOpacity(0.3),
              ),
            ),
            child: Row(
              children: [
                Icon(
                  Icons.wifi_off,
                  color: theme.colorScheme.error,
                  size: 18,
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: Text(
                    pendingCount > 0 
                      ? 'Hors ligne - $pendingCount requête${pendingCount > 1 ? 's' : ''} en attente'
                      : 'Aucune connexion Internet. Certaines fonctionnalités peuvent être limitées.',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: theme.colorScheme.error,
                    ),
                  ),
                ),
                if (pendingCount > 0)
                  AnimatedBuilder(
                    animation: _animation,
                    builder: (context, child) {
                      return Opacity(
                        opacity: _animation.value,
                        child: Container(
                          margin: const EdgeInsets.only(left: 8),
                          padding: const EdgeInsets.all(4),
                          decoration: BoxDecoration(
                            color: Colors.orange,
                            shape: BoxShape.circle,
                          ),
                          child: Text(
                            pendingCount.toString(),
                            style: const TextStyle(
                              color: Colors.white,
                              fontSize: 11,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ),
                      );
                    },
                  ),
              ],
            ),
          );
        } else if (isConnected && widget.showConnectionType) {
          return _buildConnectedIndicator(
            context, 
            connectionStatus, 
            connectionType, 
            theme, 
            pendingCount
          );
        }

        // Si aucune condition n'est remplie
        return const SizedBox.shrink();
      },
    );
  }

  Widget _buildConnectedIndicator(
    BuildContext context,
    List<ConnectivityResult> connectionStatus,
    String connectionType,
    ThemeData theme,
    int pendingCount,
  ) {
    // Obtenir la couleur et l'icône en fonction du type de connexion
    final color = _getConnectionColor(connectionStatus, theme);
    final icon = _getConnectionIcon(connectionStatus);

    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return GestureDetector(
          onTap: pendingCount > 0 ? () => _showPendingRequestsDialog(context) : null,
          child: Container(
            padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
            decoration: BoxDecoration(
              color: pendingCount > 0
                ? Colors.orange.withOpacity(0.1 * _animation.value)
                : color.withOpacity(0.1),
              borderRadius: BorderRadius.circular(16),
              border: Border.all(
                color: pendingCount > 0
                  ? Colors.orange.withOpacity(0.3 * _animation.value)
                  : color.withOpacity(0.3),
              ),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  pendingCount > 0 ? Icons.sync : icon,
                  color: pendingCount > 0 ? Colors.orange : color,
                  size: 14,
                ),
                const SizedBox(width: 4),
                Text(
                  pendingCount > 0
                    ? '$pendingCount en attente'
                    : connectionType,
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: pendingCount > 0 ? Colors.orange : color,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Widget _buildBasicIndicator(
    BuildContext context,
    bool isConnected,
    String connectionType,
    List<ConnectivityResult> connectionStatus,
    ThemeData theme,
    int pendingCount,
  ) {
    if (!isConnected && widget.showErrorMessage) {
      return Container(
        padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
        margin: const EdgeInsets.only(bottom: 8),
        decoration: BoxDecoration(
          color: theme.colorScheme.error.withOpacity(0.1),
          borderRadius: BorderRadius.circular(8),
          border: Border.all(
            color: theme.colorScheme.error.withOpacity(0.3),
          ),
        ),
        child: Row(
          children: [
            Icon(
              Icons.wifi_off,
              color: theme.colorScheme.error,
              size: 18,
            ),
            const SizedBox(width: 8),
            Expanded(
              child: Text(
                'Aucune connexion Internet. Certaines fonctionnalités peuvent être limitées.',
                style: theme.textTheme.bodySmall?.copyWith(
                  color: theme.colorScheme.error,
                ),
              ),
            ),
          ],
        ),
      );
    } else if (isConnected && widget.showConnectionType) {
      final color = _getConnectionColor(connectionStatus, theme);
      final icon = _getConnectionIcon(connectionStatus);

      return Container(
        padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
        decoration: BoxDecoration(
          color: color.withOpacity(0.1),
          borderRadius: BorderRadius.circular(16),
          border: Border.all(
            color: color.withOpacity(0.3),
          ),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(
              icon,
              color: color,
              size: 14,
            ),
            const SizedBox(width: 4),
            Text(
              connectionType,
              style: theme.textTheme.bodySmall?.copyWith(
                color: color,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      );
    }

    return const SizedBox.shrink();
  }

  /// Retourne l'icône correspondant au type de connexion
  IconData _getConnectionIcon(List<ConnectivityResult> statusList) {
    // Utiliser le premier type de connexion qui n'est pas 'none'
    ConnectivityResult status = statusList.firstWhere(
        (result) => result != ConnectivityResult.none,
        orElse: () => ConnectivityResult.none);

    switch (status) {
      case ConnectivityResult.wifi:
        return Icons.wifi;
      case ConnectivityResult.mobile:
        return Icons.signal_cellular_alt;
      case ConnectivityResult.ethernet:
        return Icons.lan;
      case ConnectivityResult.bluetooth:
        return Icons.bluetooth;
      case ConnectivityResult.vpn:
        return Icons.vpn_key;
      default:
        return Icons.wifi_off;
    }
  }

  /// Retourne la couleur correspondant au type de connexion
  Color _getConnectionColor(
      List<ConnectivityResult> statusList, ThemeData theme) {
    // Utiliser le premier type de connexion qui n'est pas 'none'
    ConnectivityResult status = statusList.firstWhere(
        (result) => result != ConnectivityResult.none,
        orElse: () => ConnectivityResult.none);

    switch (status) {
      case ConnectivityResult.wifi:
        return Colors.green;
      case ConnectivityResult.mobile:
        return Colors.blue;
      case ConnectivityResult.ethernet:
        return Colors.purple;
      case ConnectivityResult.bluetooth:
        return Colors.indigo;
      case ConnectivityResult.vpn:
        return Colors.orange;
      default:
        return theme.colorScheme.error;
    }
  }

  /// Affiche une boîte de dialogue pour gérer les requêtes en attente
  void _showPendingRequestsDialog(BuildContext context) {
    final box = Hive.box<PendingRequest>(AppKeys.pendingRequestsBoxName);

    showDialog(
      context: context,
      builder: (dialogContext) => ValueListenableBuilder<Box<PendingRequest>>(
        valueListenable: box.listenable(),
        builder: (context, box, _) {
          final requests = box.values.toList()
            ..sort((a, b) => a.createdAt.compareTo(b.createdAt));

          // Si plus de requêtes, fermer la dialog
          if (requests.isEmpty) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
              if (dialogContext.mounted) {
                Navigator.of(dialogContext).pop();
              }
            });
          }

          return AlertDialog(
        title: Row(
          children: [
            const Icon(Icons.sync_problem, color: Colors.orange),
            const SizedBox(width: 8),
            Text('Requêtes en attente (${requests.length})'),
          ],
        ),
        content: SizedBox(
          width: double.maxFinite,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              // Actions globales
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  ElevatedButton.icon(
                    onPressed: () async {
                      // Réessayer toutes les requêtes
                      Navigator.of(dialogContext).pop();
                      await ApiService.instance.processPendingRequests();
                      if (context.mounted) {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text('Traitement des requêtes en cours...'),
                            backgroundColor: Colors.blue,
                          ),
                        );
                      }
                    },
                    icon: const Icon(Icons.refresh),
                    label: const Text('Tout réessayer'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue,
                      foregroundColor: Colors.white,
                    ),
                  ),
                  ElevatedButton.icon(
                    onPressed: () async {
                      // Confirmer avant de tout supprimer
                      final confirmed = await showDialog<bool>(
                        context: dialogContext,
                        builder: (confirmContext) => AlertDialog(
                          title: const Text('Confirmation'),
                          content: const Text(
                            'Êtes-vous sûr de vouloir supprimer toutes les requêtes en attente ?',
                          ),
                          actions: [
                            TextButton(
                              onPressed: () => Navigator.of(confirmContext).pop(false),
                              child: const Text('Annuler'),
                            ),
                            TextButton(
                              onPressed: () => Navigator.of(confirmContext).pop(true),
                              child: const Text('Supprimer'),
                            ),
                          ],
                        ),
                      );

                      if (confirmed == true) {
                        await box.clear();
                        if (dialogContext.mounted) {
                          Navigator.of(dialogContext).pop();
                        }
                        if (context.mounted) {
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                              content: Text('Toutes les requêtes ont été supprimées'),
                              backgroundColor: Colors.green,
                            ),
                          );
                        }
                      }
                    },
                    icon: const Icon(Icons.delete_sweep),
                    label: const Text('Tout supprimer'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.red,
                      foregroundColor: Colors.white,
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              const Divider(),
              const SizedBox(height: 8),
              // Liste des requêtes
              Flexible(
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: requests.length,
                  itemBuilder: (context, index) {
                    final request = requests[index];
                    final hasConflict = request.metadata?['hasConflict'] == true;
                    final hasErrors = request.retryCount >= 5;

                    return Card(
                      color: hasConflict
                          ? Colors.red.shade50
                          : hasErrors
                              ? Colors.orange.shade50
                              : null,
                      child: ListTile(
                        leading: Icon(
                          hasConflict
                              ? Icons.error
                              : hasErrors
                                  ? Icons.warning
                                  : Icons.sync,
                          color: hasConflict
                              ? Colors.red
                              : hasErrors
                                  ? Colors.orange
                                  : Colors.blue,
                        ),
                        title: Text('${request.method} ${request.path}'),
                        subtitle: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              'Créé: ${_formatDate(request.createdAt)}',
                              style: const TextStyle(fontSize: 11),
                            ),
                            if (request.retryCount > 0)
                              Text(
                                'Tentatives: ${request.retryCount}',
                                style: const TextStyle(fontSize: 11),
                              ),
                            if (hasConflict)
                              const Text(
                                'CONFLIT (409)',
                                style: TextStyle(
                                  fontSize: 11,
                                  color: Colors.red,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            if (hasErrors)
                              const Text(
                                'ÉCHEC (5 tentatives)',
                                style: TextStyle(
                                  fontSize: 11,
                                  color: Colors.orange,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                          ],
                        ),
                        trailing: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            // Bouton détails
                            IconButton(
                              icon: const Icon(Icons.info_outline, size: 20),
                              tooltip: 'Détails',
                              onPressed: () => _showRequestDetails(dialogContext, request),
                            ),
                            // Bouton réessayer
                            if (hasConflict || hasErrors)
                              IconButton(
                                icon: const Icon(Icons.refresh, size: 20),
                                tooltip: 'Réessayer',
                                color: Colors.blue,
                                onPressed: () async {
                                  await ApiService.instance.resolveConflictByRetry(request.id);
                                  if (dialogContext.mounted) {
                                    Navigator.of(dialogContext).pop();
                                  }
                                  if (context.mounted) {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(
                                        content: Text('Requête marquée pour réessai'),
                                        backgroundColor: Colors.blue,
                                      ),
                                    );
                                  }
                                },
                              ),
                            // Bouton supprimer
                            IconButton(
                              icon: const Icon(Icons.delete_outline, size: 20),
                              tooltip: 'Supprimer',
                              color: Colors.red,
                              onPressed: () async {
                                if (hasConflict) {
                                  await ApiService.instance.resolveConflictByDeletion(request.id);
                                } else {
                                  await box.delete(request.key);
                                }
                                // La dialog se ferme automatiquement via ValueListenableBuilder si box vide
                              },
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(dialogContext).pop(),
            child: const Text('Fermer'),
          ),
        ],
      );
        },
      ),
    );
  }

  /// Affiche les détails d'une requête
  void _showRequestDetails(BuildContext context, PendingRequest request) {
    showDialog(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('Détails de la requête'),
        content: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              _buildDetailRow('Méthode', request.method),
              _buildDetailRow('Chemin', request.path),
              _buildDetailRow('Créé le', _formatDate(request.createdAt)),
              _buildDetailRow('Tentatives', request.retryCount.toString()),
              if (request.tempId != null)
                _buildDetailRow('ID temporaire', request.tempId!),
              if (request.errorMessage != null)
                _buildDetailRow('Erreur', request.errorMessage!, isError: true),
              if (request.metadata != null && request.metadata!.isNotEmpty)
                _buildDetailRow('Métadonnées', request.metadata.toString()),
              if (request.data != null) ...[
                const SizedBox(height: 8),
                const Text(
                  'Données:',
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
                const SizedBox(height: 4),
                Container(
                  padding: const EdgeInsets.all(8),
                  decoration: BoxDecoration(
                    color: Colors.grey.shade100,
                    borderRadius: BorderRadius.circular(4),
                  ),
                  child: Text(
                    request.data.toString(),
                    style: const TextStyle(fontSize: 11, fontFamily: 'monospace'),
                  ),
                ),
              ],
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(dialogContext).pop(),
            child: const Text('Fermer'),
          ),
        ],
      ),
    );
  }

  Widget _buildDetailRow(String label, String value, {bool isError = false}) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 100,
            child: Text(
              '$label:',
              style: const TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
          Expanded(
            child: Text(
              value,
              style: TextStyle(
                color: isError ? Colors.red : null,
              ),
            ),
          ),
        ],
      ),
    );
  }

  String _formatDate(DateTime date) {
    final now = DateTime.now();
    final diff = now.difference(date);

    if (diff.inMinutes < 1) {
      return 'Il y a quelques secondes';
    } else if (diff.inHours < 1) {
      return 'Il y a ${diff.inMinutes} min';
    } else if (diff.inDays < 1) {
      return 'Il y a ${diff.inHours} h';
    } else {
      return 'Il y a ${diff.inDays} jour${diff.inDays > 1 ? 's' : ''}';
    }
  }
}
