import 'package:em2rp/models/container_model.dart';
import 'package:em2rp/models/equipment_model.dart';
import 'package:em2rp/services/api_service.dart';
import 'package:em2rp/services/data_service.dart';

class ContainerService {
  final ApiService _apiService = apiService;
  final DataService _dataService = DataService(apiService);

  // ============================================================================
  // CRUD Operations - Utilise le backend sécurisé
  // ============================================================================

  /// Créer un nouveau container (via Cloud Function)
  Future<void> createContainer(ContainerModel container) async {
    try {
      await _apiService.call('createContainer', container.toMap()..['id'] = container.id);
    } catch (e) {
      print('Error creating container: $e');
      rethrow;
    }
  }

  /// Mettre à jour un container (via Cloud Function)
  Future<void> updateContainer(String id, Map<String, dynamic> data) async {
    try {
      await _apiService.call('updateContainer', {
        'containerId': id,
        'data': data,
      });
    } catch (e) {
      print('Error updating container: $e');
      rethrow;
    }
  }

  /// Supprimer un container (via Cloud Function)
  Future<void> deleteContainer(String id) async {
    try {
      await _apiService.call('deleteContainer', {'containerId': id});
      // Note: La Cloud Function gère maintenant la mise à jour des équipements
    } catch (e) {
      print('Error deleting container: $e');
      rethrow;
    }
  }

  /// Récupérer un container par ID
  Future<ContainerModel?> getContainerById(String id) async {
    try {
      final containersData = await _dataService.getContainersByIds([id]);
      if (containersData.isEmpty) return null;

      return ContainerModel.fromMap(containersData.first, id);
    } catch (e) {
      print('Error getting container: $e');
      rethrow;
    }
  }

  /// Récupérer tous les containers
  Future<List<ContainerModel>> getContainers({
    ContainerType? type,
    EquipmentStatus? status,
    String? searchQuery,
  }) async {
    try {
      final containersData = await _dataService.getContainers();

      var containerList = containersData
          .map((data) => ContainerModel.fromMap(data, data['id'] as String))
          .toList();

      // Filtres côté client
      if (type != null) {
        containerList = containerList
            .where((c) => c.type == type)
            .toList();
      }

      if (status != null) {
        containerList = containerList
            .where((c) => c.status == status)
            .toList();
      }

      if (searchQuery != null && searchQuery.isNotEmpty) {
        final lowerSearch = searchQuery.toLowerCase();
        containerList = containerList.where((container) {
          return container.name.toLowerCase().contains(lowerSearch) ||
                 container.id.toLowerCase().contains(lowerSearch);
        }).toList();
      }

      return containerList;
    } catch (e) {
      print('Error getting containers: $e');
      rethrow;
    }
  }

  /// Ajouter un équipement à un container
  Future<Map<String, dynamic>> addEquipmentToContainer({
    required String containerId,
    required String equipmentId,
    String? userId,
  }) async {
    try {
      final response = await _apiService.call('addEquipmentToContainer', {
        'containerId': containerId,
        'equipmentId': equipmentId,
        if (userId != null) 'userId': userId,
      });

      return {
        'success': response['success'] ?? false,
        'message': response['message'] ?? '',
        'warnings': response['warnings'],
      };
    } catch (e) {
      print('Error adding equipment to container: $e');
      return {'success': false, 'message': 'Erreur: $e'};
    }
  }

  /// Retirer un équipement d'un container
  Future<void> removeEquipmentFromContainer({
    required String containerId,
    required String equipmentId,
    String? userId,
  }) async {
    try {
      await _apiService.call('removeEquipmentFromContainer', {
        'containerId': containerId,
        'equipmentId': equipmentId,
        if (userId != null) 'userId': userId,
      });
    } catch (e) {
      print('Error removing equipment from container: $e');
      rethrow;
    }
  }

  Future<Map<String, dynamic>> checkContainerAvailability({
    required String containerId,
    required DateTime startDate,
    required DateTime endDate,
    String? excludeEventId,
  }) async {
    try {
      final result = await _dataService.checkContainerAvailability(
        containerId: containerId,
        startDate: startDate,
        endDate: endDate,
        excludeEventId: excludeEventId,
      );
      return {
        'available': result['isAvailable'] ?? false,
        'message': result['isAvailable'] == true
            ? 'Container et tout son contenu disponibles'
            : 'Container non disponible ou en conflit',
        'conflictType': result['conflictType'],
        'containerConflicts': result['containerConflicts'],
        'equipmentConflicts': result['equipmentConflicts'],
      };
    } catch (e) {
      print('Error checking container availability: $e');
      return {'available': false, 'message': 'Erreur: $e'};
    }
  }

  /// Récupérer les équipements d'un container
  Future<List<EquipmentModel>> getContainerEquipment(String containerId) async {
    try {
      final container = await getContainerById(containerId);
      if (container == null) return [];

      if (container.equipmentIds.isEmpty) return [];

      final equipmentsData = await _dataService.getEquipmentsByIds(container.equipmentIds);

      return equipmentsData
          .map((data) {
            final id = data['id'] as String;
            return EquipmentModel.fromMap(data, id);
          })
          .toList();
    } catch (e) {
      print('Error getting container equipment: $e');
      rethrow;
    }
  }

  /// Trouver tous les containers contenant un équipement spécifique
  Future<List<ContainerModel>> findContainersWithEquipment(String equipmentId) async {
    try {
      final containersData = await _dataService.getContainersByEquipment(equipmentId);

      return containersData
          .map((data) => ContainerModel.fromMap(data, data['id'] as String))
          .toList();
    } catch (e) {
      print('Error finding containers with equipment: $e');
      rethrow;
    }
  }

  /// Ajouter une entrée d'historique
  Future<void> _addHistoryEntry({
    required String containerId,
    required String action,
    String? equipmentId,
    String? previousValue,
    String? newValue,
    String? userId,
  }) async {
    try {
      final container = await getContainerById(containerId);
      if (container == null) return;

      final entry = ContainerHistoryEntry(
        timestamp: DateTime.now(),
        action: action,
        equipmentId: equipmentId,
        previousValue: previousValue,
        newValue: newValue,
        userId: userId,
      );

      final updatedHistory = [...container.history, entry];

      // Limiter l'historique aux 100 dernières entrées
      final limitedHistory = updatedHistory.length > 100
          ? updatedHistory.sublist(updatedHistory.length - 100)
          : updatedHistory;

      await updateContainer(containerId, {
        'history': limitedHistory.map((e) => e.toMap()).toList(),
      });
    } catch (e) {
      print('Error adding history entry: $e');
      // Ne pas throw pour éviter de bloquer l'opération principale
    }
  }

  /// Vérifier si un ID de container existe déjà
  Future<bool> checkContainerIdExists(String id) async {
    try {
      final container = await getContainerById(id);
      return container != null;
    } catch (e) {
      print('Error checking container ID: $e');
      return false;
    }
  }
}

