import 'dart:async'; // Serve per il Timer del debounce import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flux/features/customers/data/customer_repository.dart'; import 'package:flux/features/customers/models/customer_model.dart'; import 'package:get_it/get_it.dart'; part 'customer_state.dart'; class CustomerCubit extends Cubit { final CustomerRepository _repository = GetIt.I(); // Variabile per gestire il debounce della ricerca Timer? _searchDebounce; CustomerCubit() : super(const CustomerState()); // --- LETTURA --- Future loadCustomers(String companyId) async { emit(state.copyWith(status: CustomerStatus.loading)); try { final customers = await _repository.getCustomers(companyId); emit( state.copyWith(status: CustomerStatus.success, customers: customers), ); } catch (e) { emit( state.copyWith( status: CustomerStatus.failure, errorMessage: e.toString(), ), ); } } // --- CREAZIONE --- Future createCustomer(CustomerModel customer) async { emit(state.copyWith(status: CustomerStatus.loading)); try { final newCustomer = await _repository.createCustomer(customer); // Aggiorniamo la lista locale aggiungendo il nuovo cliente in cima final updatedList = List.from(state.customers) ..insert(0, newCustomer); emit( state.copyWith( status: CustomerStatus.success, customers: updatedList, lastCreatedCustomer: newCustomer, ), ); } catch (e) { emit( state.copyWith( status: CustomerStatus.failure, errorMessage: e.toString(), ), ); } } // --- AGGIORNAMENTO --- Future updateCustomer(CustomerModel customer) async { emit(state.copyWith(status: CustomerStatus.loading)); try { final updatedCustomer = await _repository.updateCustomer(customer); final updatedList = List.from(state.customers); final index = updatedList.indexWhere((c) => c.id == updatedCustomer.id); if (index != -1) { updatedList[index] = updatedCustomer; } emit( state.copyWith( status: CustomerStatus.success, customers: updatedList, lastCreatedCustomer: updatedCustomer, // Utile se modifichi un cliente appena creato ), ); } catch (e) { emit( state.copyWith( status: CustomerStatus.failure, errorMessage: e.toString(), ), ); } } // --- RICERCA CON DEBOUNCE --- void searchCustomers(String companyId, String query) { // 1. Se c'è già una ricerca in attesa (l'utente sta digitando veloce), la annulliamo if (_searchDebounce?.isActive ?? false) _searchDebounce!.cancel(); // 2. Facciamo partire un timer di 400 millisecondi _searchDebounce = Timer(const Duration(milliseconds: 400), () async { // Se cancella tutto e la query è vuota, ricarichiamo la lista base if (query.trim().isEmpty) { await loadCustomers(companyId); return; } // Nessun "loading" state qui, per evitare sfarfallii visivi mentre si scrive try { final results = await _repository.searchCustomers(companyId, query); emit( state.copyWith(status: CustomerStatus.success, customers: results), ); } catch (e) { emit( state.copyWith( status: CustomerStatus.failure, errorMessage: e.toString(), ), ); } }); } // Pulizia della memoria quando il Cubit viene distrutto @override Future close() { _searchDebounce?.cancel(); return super.close(); } }