import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:file_picker/file_picker.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:em2rp/models/event_model.dart';
import 'package:em2rp/models/event_type_model.dart';
import 'package:em2rp/models/user_model.dart';
import 'package:em2rp/services/api_service.dart';
import 'package:em2rp/services/data_service.dart';
import 'package:em2rp/services/alert_service.dart';
import 'dart:developer' as developer;

class EventFormService {
  static final ApiService _apiService = apiService;
  static final DataService _dataService = DataService(FirebaseFunctionsApiService());

  // ============================================================================
  // READ Operations - Utilise l'API (sécurisé avec permissions côté serveur)
  // ============================================================================

  static Future<List<EventTypeModel>> fetchEventTypes() async {
    developer.log('Fetching event types via API...', name: 'EventFormService');
    try {
      final eventTypesData = await _dataService.getEventTypes();
      final eventTypes = eventTypesData.map((data) => EventTypeModel.fromMap(data, data['id'] as String)).toList();
      developer.log('${eventTypes.length} event types loaded.', name: 'EventFormService');
      return eventTypes;
    } catch (e, s) {
      developer.log('Error fetching event types', name: 'EventFormService', error: e, stackTrace: s);
      throw Exception("Could not load event types. Please check permissions.");
    }
  }

  static Future<List<UserModel>> fetchUsers() async {
    try {
      final usersData = await _dataService.getUsers();
      return usersData.map((data) => UserModel.fromMap(data, data['id'] as String)).toList();
    } catch (e) {
      developer.log('Error fetching users', name: 'EventFormService', error: e);
      throw Exception("Could not load users.");
    }
  }

  // ============================================================================
  // STORAGE - Reste inchangé (déjà via Cloud Function)
  // ============================================================================

  static Future<List<Map<String, String>>> uploadFiles(List<PlatformFile> files) async {
    List<Map<String, String>> uploadedFiles = [];

    for (final file in files) {
      final fileBytes = file.bytes;
      final fileName = file.name;

      if (fileBytes != null) {
        final ref = FirebaseStorage.instance.ref().child(
            'events/temp/${DateTime.now().millisecondsSinceEpoch}_$fileName');
        final uploadTask = await ref.putData(fileBytes);
        final url = await uploadTask.ref.getDownloadURL();
        uploadedFiles.add({'name': fileName, 'url': url});
      } else {
        throw Exception("Impossible de lire le fichier $fileName");
      }
    }

    return uploadedFiles;
  }

  static Future<String?> moveEventFileHttp({
    required String sourcePath,
    required String destinationPath,
  }) async {
    final url = Uri.parse('https://europe-west9-em2rp-951dc.cloudfunctions.net/moveEventFileV2');
    final user = FirebaseAuth.instance.currentUser;
    final idToken = await user?.getIdToken();

    final response = await http.post(
      url,
      headers: {
        'Content-Type': 'application/json',
        if (idToken != null) 'Authorization': 'Bearer $idToken',
      },
      body: jsonEncode({
        'data': {
          'sourcePath': sourcePath,
          'destinationPath': destinationPath,
        }
      }),
    );

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      if (data['url'] != null) {
        return data['url'] as String;
      } else if (data['result'] != null && data['result']['url'] != null) {
        return data['result']['url'] as String;
      }
      return null;
    } else {
      print('Erreur Cloud Function: \n${response.body}');
      return null;
    }
  }

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

  static Future<String> createEvent(EventModel event) async {
    try {
      final result = await _apiService.call('createEvent', event.toMap());
      final eventId = result['id'] as String;

      // NOUVEAU : Créer alerte automatique pour les utilisateurs assignés
      try {
        await AlertService().createEventCreatedAlert(
          eventId: eventId,
          eventName: event.name,
          eventDate: event.startDateTime,
        );
        developer.log('Alert created for new event: $eventId', name: 'EventFormService');
      } catch (alertError) {
        // Ne pas bloquer la création de l'événement si l'alerte échoue
        developer.log('Warning: Could not create alert for event',
          name: 'EventFormService',
          error: alertError);
      }

      return eventId;
    } catch (e) {
      developer.log('Error creating event', name: 'EventFormService', error: e);
      rethrow;
    }
  }

  static Future<void> updateEvent(EventModel event) async {
    try {
      if (event.id.isEmpty) {
        throw Exception("Cannot update event: Event ID is empty");
      }

      developer.log('Updating event with ID: ${event.id}', name: 'EventFormService');

      final eventData = event.toMap();
      eventData['eventId'] = event.id;
      await _apiService.call('updateEvent', eventData);

      developer.log('Event updated successfully', name: 'EventFormService');

      // NOUVEAU : Créer alerte automatique pour les utilisateurs assignés
      try {
        final currentUserId = FirebaseAuth.instance.currentUser?.uid;
        if (currentUserId != null) {
          await AlertService().createEventModifiedAlert(
            eventId: event.id,
            eventName: event.name,
            modification: 'Informations modifiées',
          );
          developer.log('Alert created for modified event: ${event.id}', name: 'EventFormService');
        }
      } catch (alertError) {
        // Ne pas bloquer la modification de l'événement si l'alerte échoue
        developer.log('Warning: Could not create alert for event modification',
          name: 'EventFormService',
          error: alertError);
      }
    } catch (e) {
      developer.log('Error updating event', name: 'EventFormService', error: e);
      rethrow;
    }
  }

  static Future<void> deleteEvent(String eventId) async {
    try {
      await _apiService.call('deleteEvent', {'eventId': eventId});
    } catch (e) {
      developer.log('Error deleting event', name: 'EventFormService', error: e);
      rethrow;
    }
  }

  static Future<List<Map<String, String>>> moveFilesToEvent(
      List<Map<String, String>> tempFiles, String eventId) async {
    List<Map<String, String>> newFiles = [];

    for (final file in tempFiles) {
      final fileName = file['name']!;
      final oldUrl = file['url']!;

      String sourcePath;
      final tempPattern = RegExp(r'events/temp/[^?]+');
      final match = tempPattern.firstMatch(oldUrl);
      if (match != null) {
        sourcePath = match.group(0)!;
      } else {
        final tempFileName = Uri.decodeComponent(oldUrl.split('/').last.split('?').first);
        sourcePath = tempFileName;
      }

      final destinationPath = 'events/$eventId/$fileName';
      final newUrl = await moveEventFileHttp(
        sourcePath: sourcePath,
        destinationPath: destinationPath,
      );

      if (newUrl != null) {
        newFiles.add({'name': fileName, 'url': newUrl});
      } else {
        newFiles.add({'name': fileName, 'url': oldUrl});
      }
    }

    return newFiles;
  }

  static Future<void> updateEventDocuments(String eventId, List<Map<String, String>> documents) async {
    try {
      if (eventId.isEmpty) {
        throw Exception("Event ID cannot be empty");
      }

      developer.log('Updating event documents for ID: $eventId (${documents.length} documents)', name: 'EventFormService');

      await _apiService.call('updateEvent', {
        'eventId': eventId,
        'documents': documents,
      });

      developer.log('Event documents updated successfully', name: 'EventFormService');
    } catch (e) {
      developer.log('Error updating event documents', name: 'EventFormService', error: e);
      throw Exception("Could not update event documents.");
    }
  }
}
