import 'dart:async';

import 'package:flutter/material.dart';

import '../../data/services/realtime_notification_service.dart';

/// Widget qui écoute les streams de notifications et affiche des toasts.
///
/// Ce widget doit wrapper l'application pour avoir accès au BuildContext
/// et pouvoir afficher les notifications visuelles (SnackBar, Dialog, etc.).
///
/// **Usage :**
/// ```dart
/// MaterialApp(
///   home: RealtimeNotificationHandler(
///     realtimeService: _realtimeService,
///     child: HomeScreen(),
///   ),
/// );
/// ```
class RealtimeNotificationHandler extends StatefulWidget {
  const RealtimeNotificationHandler({
    required this.child,
    required this.realtimeService,
    super.key,
  });

  final Widget child;
  final RealtimeNotificationService realtimeService;

  @override
  State<RealtimeNotificationHandler> createState() => _RealtimeNotificationHandlerState();
}

class _RealtimeNotificationHandlerState extends State<RealtimeNotificationHandler> {
  StreamSubscription<FriendRequestNotification>? _friendRequestSub;
  StreamSubscription<SystemNotification>? _systemNotificationSub;
  StreamSubscription<MessageAlert>? _messageAlertSub;

  @override
  void initState() {
    super.initState();
    _setupListeners();
  }

  void _setupListeners() {
    // Écouter les demandes d'amitié
    _friendRequestSub = widget.realtimeService.friendRequestStream.listen((notification) {
      _showToast(notification.toDisplayMessage(), type: _getNotificationType(notification.type));
    });

    // Écouter les notifications système
    _systemNotificationSub = widget.realtimeService.systemNotificationStream.listen((notification) {
      _showSystemNotification(notification);
    });

    // Écouter les alertes de messages
    _messageAlertSub = widget.realtimeService.messageAlertStream.listen((alert) {
      _showToast('Nouveau message de ${alert.senderName}', type: NotificationType.info);
    });
  }

  /// Détermine le type de notification pour le style du toast.
  NotificationType _getNotificationType(String type) {
    switch (type) {
      case 'accepted':
        return NotificationType.success;
      case 'rejected':
        return NotificationType.warning;
      case 'received':
      default:
        return NotificationType.info;
    }
  }

  /// Affiche un toast (SnackBar) avec le message.
  void _showToast(String message, {NotificationType type = NotificationType.info}) {
    if (!mounted) return;

    final color = _getColorForType(type);
    final icon = _getIconForType(type);

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Row(
          children: [
            Icon(icon, color: Colors.white, size: 20),
            const SizedBox(width: 12),
            Expanded(
              child: Text(
                message,
                style: const TextStyle(color: Colors.white),
              ),
            ),
          ],
        ),
        backgroundColor: color,
        behavior: SnackBarBehavior.floating,
        duration: const Duration(seconds: 4),
        action: SnackBarAction(
          label: 'OK',
          textColor: Colors.white,
          onPressed: () {
            ScaffoldMessenger.of(context).hideCurrentSnackBar();
          },
        ),
      ),
    );
  }

  /// Affiche une notification système plus élaborée.
  void _showSystemNotification(SystemNotification notification) {
    if (!mounted) return;

    final color = _getColorForSystemNotificationType(notification.type);
    final icon = _getIconForSystemNotificationType(notification.type);

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                Icon(icon, color: Colors.white, size: 20),
                const SizedBox(width: 12),
                Expanded(
                  child: Text(
                    notification.title,
                    style: const TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                      fontSize: 14,
                    ),
                  ),
                ),
              ],
            ),
            if (notification.message.isNotEmpty) ...[
              const SizedBox(height: 4),
              Padding(
                padding: const EdgeInsets.only(left: 32),
                child: Text(
                  notification.message,
                  style: const TextStyle(color: Colors.white70, fontSize: 12),
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ],
          ],
        ),
        backgroundColor: color,
        behavior: SnackBarBehavior.floating,
        duration: const Duration(seconds: 5),
        action: SnackBarAction(
          label: 'OK',
          textColor: Colors.white,
          onPressed: () {
            ScaffoldMessenger.of(context).hideCurrentSnackBar();
          },
        ),
      ),
    );
  }

  /// Retourne la couleur appropriée selon le type de notification.
  Color _getColorForType(NotificationType type) {
    switch (type) {
      case NotificationType.success:
        return Colors.green.shade600;
      case NotificationType.warning:
        return Colors.orange.shade600;
      case NotificationType.error:
        return Colors.red.shade600;
      case NotificationType.info:
      default:
        return Colors.blue.shade600;
    }
  }

  /// Retourne l'icône appropriée selon le type de notification.
  IconData _getIconForType(NotificationType type) {
    switch (type) {
      case NotificationType.success:
        return Icons.check_circle;
      case NotificationType.warning:
        return Icons.warning;
      case NotificationType.error:
        return Icons.error;
      case NotificationType.info:
      default:
        return Icons.info;
    }
  }

  /// Retourne la couleur appropriée selon le type de notification système.
  Color _getColorForSystemNotificationType(String type) {
    switch (type.toLowerCase()) {
      case 'event':
        return Colors.blue.shade600;
      case 'friend':
        return Colors.green.shade600;
      case 'reminder':
        return Colors.orange.shade600;
      default:
        return Colors.grey.shade700;
    }
  }

  /// Retourne l'icône appropriée selon le type de notification système.
  IconData _getIconForSystemNotificationType(String type) {
    switch (type.toLowerCase()) {
      case 'event':
        return Icons.event;
      case 'friend':
        return Icons.people;
      case 'reminder':
        return Icons.notifications;
      default:
        return Icons.info;
    }
  }

  @override
  void dispose() {
    _friendRequestSub?.cancel();
    _systemNotificationSub?.cancel();
    _messageAlertSub?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => widget.child;
}

/// Enum pour les types de notifications toast.
enum NotificationType {
  success,
  warning,
  error,
  info,
}
