import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import '../models/alert_model.dart';
import '../utils/debug_log.dart';
import 'api_service.dart' show FirebaseFunctionsApiService;
/// Service de gestion des alertes
/// Architecture simplifiée : le client appelle uniquement les Cloud Functions
/// Toute la logique métier est gérée côté backend
class AlertService {
  FirebaseFirestore get _firestore => FirebaseFirestore.instance;
  FirebaseAuth get _auth => FirebaseAuth.instance;

  /// Stream des alertes pour l'utilisateur connecté
  Stream<List<AlertModel>> getAlertsStream() {
    final user = _auth.currentUser;
    if (user == null) {
      DebugLog.info('[AlertService] Pas d\'utilisateur connecté');
      return Stream.value([]);
    }

    DebugLog.info('[AlertService] Stream alertes pour utilisateur: ${user.uid}');

    return _firestore
        .collection('alerts')
        .where('assignedTo', arrayContains: user.uid)
        .where('status', isEqualTo: 'ACTIVE')
        .orderBy('createdAt', descending: true)
        .snapshots()
        .map((snapshot) {
      final alerts = snapshot.docs
          .map((doc) => AlertModel.fromFirestore(doc))
          .toList();

      DebugLog.info('[AlertService] ${alerts.length} alertes actives');
      return alerts;
    });
  }

  /// Récupère les alertes non lues
  Future<List<AlertModel>> getUnreadAlerts() async {
    final user = _auth.currentUser;
    if (user == null) return [];

    try {
      final snapshot = await _firestore
          .collection('alerts')
          .where('assignedTo', arrayContains: user.uid)
          .where('isRead', isEqualTo: false)
          .where('status', isEqualTo: 'ACTIVE')
          .orderBy('createdAt', descending: true)
          .get();

      return snapshot.docs
          .map((doc) => AlertModel.fromFirestore(doc))
          .toList();
    } catch (e) {
      DebugLog.error('[AlertService] Erreur récupération alertes', e);
      return [];
    }
  }

  /// Marque une alerte comme lue
  Future<void> markAsRead(String alertId) async {
    try {
      await _firestore.collection('alerts').doc(alertId).update({
        'isRead': true,
        'readAt': FieldValue.serverTimestamp(),
      });
      DebugLog.info('[AlertService] Alerte $alertId marquée comme lue');
    } catch (e) {
      DebugLog.error('[AlertService] Erreur marquage alerte', e);
      rethrow;
    }
  }

  /// Marque toutes les alertes comme lues
  Future<void> markAllAsRead() async {
    final user = _auth.currentUser;
    if (user == null) return;

    try {
      final snapshot = await _firestore
          .collection('alerts')
          .where('assignedTo', arrayContains: user.uid)
          .where('isRead', isEqualTo: false)
          .get();

      final batch = _firestore.batch();
      for (var doc in snapshot.docs) {
        batch.update(doc.reference, {
          'isRead': true,
          'readAt': FieldValue.serverTimestamp(),
        });
      }

      await batch.commit();
      DebugLog.info('[AlertService] ${snapshot.docs.length} alertes marquées comme lues');
    } catch (e) {
      DebugLog.error('[AlertService] Erreur marquage alertes', e);
      rethrow;
    }
  }

  /// Archive une alerte
  Future<void> archiveAlert(String alertId) async {
    try {
      await _firestore.collection('alerts').doc(alertId).update({
        'status': 'ARCHIVED',
        'archivedAt': FieldValue.serverTimestamp(),
      });
      DebugLog.info('[AlertService] Alerte $alertId archivée');
    } catch (e) {
      DebugLog.error('[AlertService] Erreur archivage alerte', e);
      rethrow;
    }
  }

  /// Crée une alerte manuelle (appelée par l'utilisateur)
  /// Cette méthode appelle la Cloud Function createAlert
  Future<String> createManualAlert({
    required AlertType type,
    required AlertSeverity severity,
    required String message,
    String? title,
    String? equipmentId,
    String? eventId,
    String? actionUrl,
    Map<String, dynamic>? metadata,
  }) async {
    try {
      DebugLog.info('[AlertService] === CRÉATION ALERTE MANUELLE ===');
      DebugLog.info('[AlertService] Type: $type');
      DebugLog.info('[AlertService] Severity: $severity');

      final apiService = FirebaseFunctionsApiService();
      final result = await apiService.call(
        'createAlert',
        {
          'type': alertTypeToString(type),
          'severity': severity.name.toUpperCase(),
          'title': title,
          'message': message,
          'equipmentId': equipmentId,
          'eventId': eventId,
          'actionUrl': actionUrl,
          'metadata': metadata ?? {},
        },
      );

      final alertId = result['alertId'] as String;
      DebugLog.info('[AlertService] ✓ Alerte créée: $alertId');

      return alertId;
    } catch (e, stackTrace) {
      DebugLog.error('[AlertService] ❌ Erreur création alerte', e);
      DebugLog.error('[AlertService] Stack', stackTrace);
      rethrow;
    }
  }

  /// Stream des alertes pour un utilisateur spécifique
  Stream<List<AlertModel>> alertsStreamForUser(String userId) {
    return _firestore
        .collection('alerts')
        .where('assignedTo', arrayContains: userId)
        .where('status', isEqualTo: 'ACTIVE')
        .orderBy('createdAt', descending: true)
        .snapshots()
        .map((snapshot) => snapshot.docs
            .map((doc) => AlertModel.fromFirestore(doc))
            .toList());
  }

  /// Récupère les alertes pour un utilisateur
  Future<List<AlertModel>> getAlertsForUser(String userId) async {
    try {
      final snapshot = await _firestore
          .collection('alerts')
          .where('assignedTo', arrayContains: userId)
          .where('status', isEqualTo: 'ACTIVE')
          .orderBy('createdAt', descending: true)
          .get();

      return snapshot.docs
          .map((doc) => AlertModel.fromFirestore(doc))
          .toList();
    } catch (e) {
      DebugLog.error('[AlertService] Erreur récupération alertes', e);
      return [];
    }
  }

  /// Stream du nombre d'alertes non lues pour un utilisateur
  Stream<int> unreadCountStreamForUser(String userId) {
    return _firestore
        .collection('alerts')
        .where('assignedTo', arrayContains: userId)
        .where('isRead', isEqualTo: false)
        .where('status', isEqualTo: 'ACTIVE')
        .snapshots()
        .map((snapshot) => snapshot.docs.length);
  }

  /// Supprime une alerte
  Future<void> deleteAlert(String alertId) async {
    try {
      await _firestore.collection('alerts').doc(alertId).delete();
      DebugLog.info('[AlertService] Alerte $alertId supprimée');
    } catch (e) {
      DebugLog.error('[AlertService] Erreur suppression alerte', e);
      rethrow;
    }
  }

  /// Crée une alerte de création d'événement
  Future<void> createEventCreatedAlert({
    required String eventId,
    required String eventName,
    required DateTime eventDate,
  }) async {
    await createManualAlert(
      type: AlertType.eventCreated,
      severity: AlertSeverity.info,
      message: 'Nouvel événement créé: "$eventName" le ${_formatDate(eventDate)}',
      eventId: eventId,
      metadata: {
        'eventName': eventName,
        'eventDate': eventDate.toIso8601String(),
      },
    );
  }

  /// Crée une alerte de modification d'événement
  Future<void> createEventModifiedAlert({
    required String eventId,
    required String eventName,
    required String modification,
  }) async {
    await createManualAlert(
      type: AlertType.eventModified,
      severity: AlertSeverity.info,
      message: 'Événement "$eventName" modifié: $modification',
      eventId: eventId,
      metadata: {
        'eventName': eventName,
        'modification': modification,
      },
    );
  }

  String _formatDate(DateTime date) {
    return '${date.day}/${date.month}/${date.year}';
  }
}

