import 'dart:io';
import '../models/expense.dart';
import '../repositories/expense_repository.dart';
import 'error_service.dart';
import 'storage_service.dart'; // Pour upload des reçus

class ExpenseService {
  final ExpenseRepository _expenseRepository;
  final ErrorService _errorService;
  final StorageService _storageService;

  ExpenseService({
    required ExpenseRepository expenseRepository,
    ErrorService? errorService,
    StorageService? storageService,
  }) : _expenseRepository = expenseRepository,
       _errorService = errorService ?? ErrorService(),
       _storageService = storageService ?? StorageService();

  // Création avec validation et upload d'image
  Future<String> createExpenseWithValidation(Expense expense, File? receiptImage) async {
    try {
      // Validation métier
      _validateExpenseData(expense);
      
      // Upload du reçu si présent
      String? receiptUrl;
      if (receiptImage != null) {
        receiptUrl = await _storageService.uploadReceiptImage(
          expense.groupId,
          receiptImage,
        );
      }
      
      // Créer l'expense avec l'URL du reçu
      final expenseWithReceipt = expense.copyWith(receiptUrl: receiptUrl);
      
      return await _expenseRepository.createExpense(expenseWithReceipt);
    } catch (e) {
      _errorService.logError('ExpenseService', 'Erreur création expense: $e');
      rethrow;
    }
  }

  // Mise à jour avec validation
  Future<void> updateExpenseWithValidation(Expense expense, File? newReceiptImage) async {
    try {
      _validateExpenseData(expense);
      
      // Gérer le nouvel upload si nécessaire
      String? receiptUrl = expense.receiptUrl;
      if (newReceiptImage != null) {
        receiptUrl = await _storageService.uploadReceiptImage(
          expense.groupId,
          newReceiptImage,
        );
      }
      
      final expenseWithReceipt = expense.copyWith(
        receiptUrl: receiptUrl,
        editedAt: DateTime.now(),
        isEdited: true,
      );
      
      await _expenseRepository.updateExpense(expenseWithReceipt);
    } catch (e) {
      _errorService.logError('ExpenseService', 'Erreur update expense: $e');
      rethrow;
    }
  }

  // Validation des données
  void _validateExpenseData(Expense expense) {
    if (expense.description.trim().isEmpty) {
      throw Exception('La description est requise');
    }

    if (expense.amount <= 0) {
      throw Exception('Le montant doit être positif');
    }

    if (expense.splits.isEmpty) {
      throw Exception('Au moins un participant est requis');
    }

    final totalSplits = expense.splits.fold(0.0, (sum, split) => sum + split.amount);
    if ((totalSplits - expense.amountInEur).abs() > 0.01) {
      throw Exception('La somme des répartitions ne correspond pas au montant total');
    }
  }
}