import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter/foundation.dart';

/// Service de gestion des notifications chat
/// 
/// Gère l'envoi et la réception des notifications pour le module chat

class ChatNotificationService {
  static final ChatNotificationService _instance = ChatNotificationService._internal();
  factory ChatNotificationService() => _instance;
  ChatNotificationService._internal();

  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
  final FlutterLocalNotificationsPlugin _localNotifications = FlutterLocalNotificationsPlugin();
  
  // Callback pour les actions sur les notifications
  Function(String messageId)? onMessageTap;
  Function(Map<String, dynamic>)? onBackgroundMessage;

  /// Initialise le service de notifications
  Future<void> initialize() async {
    // Demander les permissions
    await _requestPermissions();
    
    // Initialiser les notifications locales
    await _initializeLocalNotifications();
    
    // Configurer les handlers de messages
    _configureFirebaseHandlers();
    
    // Obtenir le token du device
    await _initializeDeviceToken();
  }

  /// Demande les permissions pour les notifications
  Future<bool> _requestPermissions() async {
    NotificationSettings settings = await _firebaseMessaging.requestPermission(
      alert: true,
      badge: true,
      sound: true,
      provisional: false,
    );

    return settings.authorizationStatus == AuthorizationStatus.authorized;
  }

  /// Initialise les notifications locales
  Future<void> _initializeLocalNotifications() async {
    const AndroidInitializationSettings androidSettings = 
        AndroidInitializationSettings('@mipmap/ic_launcher');
    
    final DarwinInitializationSettings iosSettings = DarwinInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
      onDidReceiveLocalNotification: _onDidReceiveLocalNotification,
    );

    final InitializationSettings initSettings = InitializationSettings(
      android: androidSettings,
      iOS: iosSettings,
    );

    await _localNotifications.initialize(
      initSettings,
      onDidReceiveNotificationResponse: _onNotificationTap,
    );
  }

  /// Configure les handlers Firebase
  void _configureFirebaseHandlers() {
    // Message reçu quand l'app est au premier plan
    FirebaseMessaging.onMessage.listen(_onForegroundMessage);
    
    // Message reçu quand l'app est en arrière-plan
    FirebaseMessaging.onMessageOpenedApp.listen(_onBackgroundMessageOpened);
    
    // Handler pour les messages en arrière-plan terminé
    FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundHandler);
  }

  /// Handler pour les messages reçus au premier plan
  Future<void> _onForegroundMessage(RemoteMessage message) async {
    if (message.notification != null) {
      // Afficher une notification locale
      await _showLocalNotification(
        title: message.notification!.title ?? 'Nouveau message',
        body: message.notification!.body ?? '',
        payload: message.data['messageId'] ?? '',
      );
    }
  }

  /// Handler pour les messages ouverts depuis l'arrière-plan
  void _onBackgroundMessageOpened(RemoteMessage message) {
    final messageId = message.data['messageId'];
    if (messageId != null) {
      onMessageTap?.call(messageId);
    }
  }

  /// Affiche une notification locale
  Future<void> _showLocalNotification({
    required String title,
    required String body,
    required String payload,
  }) async {
    const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
      'chat_messages',
      'Messages de chat',
      channelDescription: 'Notifications pour les nouveaux messages de chat',
      importance: Importance.high,
      priority: Priority.high,
      icon: '@mipmap/ic_launcher',
    );

    const DarwinNotificationDetails iosDetails = DarwinNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    const NotificationDetails notificationDetails = NotificationDetails(
      android: androidDetails,
      iOS: iosDetails,
    );

    await _localNotifications.show(
      DateTime.now().microsecondsSinceEpoch,
      title,
      body,
      notificationDetails,
      payload: payload,
    );
  }

  /// Handler pour le clic sur une notification
  void _onNotificationTap(NotificationResponse response) {
    final payload = response.payload;
    if (payload != null) {
      onMessageTap?.call(payload);
    }
  }

  /// Handler pour les notifications iOS reçues au premier plan
  void _onDidReceiveLocalNotification(int id, String? title, String? body, String? payload) {
    // Traitement spécifique iOS si nécessaire
  }

  /// Obtient et stocke le token du device
  Future<String?> _initializeDeviceToken() async {
    String? token = await _firebaseMessaging.getToken();
    if (token != null) {
      // Envoyer le token au serveur pour stocker
      await _sendTokenToServer(token);
    }
    
    // Écouter les changements de token
    _firebaseMessaging.onTokenRefresh.listen(_sendTokenToServer);
    
    return token;
  }

  /// Envoie le token FCM au serveur
  Future<void> _sendTokenToServer(String token) async {
    try {
      // Appel API pour enregistrer le token
      // await chatApiService.registerDeviceToken(token);
      debugPrint('Device token enregistré : $token');
    } catch (e) {
      debugPrint('Erreur lors de l\'enregistrement du token : $e');
    }
  }

  /// S'abonner aux notifications pour une conversation
  Future<void> subscribeToConversation(String conversationId) async {
    await _firebaseMessaging.subscribeToTopic('chat_$conversationId');
  }

  /// Se désabonner des notifications pour une conversation
  Future<void> unsubscribeFromConversation(String conversationId) async {
    await _firebaseMessaging.unsubscribeFromTopic('chat_$conversationId');
  }

  /// Désactive temporairement les notifications
  Future<void> pauseNotifications() async {
    await _firebaseMessaging.setAutoInitEnabled(false);
  }

  /// Réactive les notifications
  Future<void> resumeNotifications() async {
    await _firebaseMessaging.setAutoInitEnabled(true);
  }
}

/// Handler pour les messages en arrière-plan
@pragma('vm:entry-point')
Future<void> _firebaseBackgroundHandler(RemoteMessage message) async {
  // Traitement des messages en arrière-plan
  debugPrint('Message reçu en arrière-plan : ${message.messageId}');
}
